diff --git a/homeassistant/components/guardian/config_flow.py b/homeassistant/components/guardian/config_flow.py
index 3a7558bb222..dae8fafb1e0 100644
--- a/homeassistant/components/guardian/config_flow.py
+++ b/homeassistant/components/guardian/config_flow.py
@@ -5,6 +5,7 @@ import voluptuous as vol
 
 from homeassistant import config_entries, core
 from homeassistant.const import CONF_IP_ADDRESS, CONF_PORT
+from homeassistant.core import callback
 
 from .const import CONF_UID, DOMAIN, LOGGER  # pylint:disable=unused-import
 
@@ -12,6 +13,20 @@ DATA_SCHEMA = vol.Schema(
     {vol.Required(CONF_IP_ADDRESS): str, vol.Required(CONF_PORT, default=7777): int}
 )
 
+UNIQUE_ID = "guardian_{0}"
+
+
+@callback
+def async_get_pin_from_discovery_hostname(hostname):
+    """Get the device's 4-digit PIN from its zeroconf-discovered hostname."""
+    return hostname.split(".")[0].split("-")[1]
+
+
+@callback
+def async_get_pin_from_uid(uid):
+    """Get the device's 4-digit PIN from its UID."""
+    return uid[-4:]
+
 
 async def validate_input(hass: core.HomeAssistant, data):
     """Validate the user input allows us to connect.
@@ -22,7 +37,6 @@ async def validate_input(hass: core.HomeAssistant, data):
         ping_data = await client.device.ping()
 
     return {
-        "title": f"Elexa Guardian ({data[CONF_IP_ADDRESS]})",
         CONF_UID: ping_data["data"]["uid"],
     }
 
@@ -37,6 +51,11 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
         """Initialize."""
         self.discovery_info = {}
 
+    async def _async_set_unique_id(self, pin):
+        """Set the config entry's unique ID (based on the device's 4-digit PIN)."""
+        await self.async_set_unique_id(UNIQUE_ID.format(pin))
+        self._abort_if_unique_id_configured()
+
     async def async_step_user(self, user_input=None):
         """Handle configuration via the UI."""
         if user_input is None:
@@ -44,9 +63,6 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
                 step_id="user", data_schema=DATA_SCHEMA, errors={}
             )
 
-        await self.async_set_unique_id(user_input[CONF_IP_ADDRESS])
-        self._abort_if_unique_id_configured()
-
         try:
             info = await validate_input(self.hass, user_input)
         except GuardianError as err:
@@ -57,8 +73,11 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
                 errors={CONF_IP_ADDRESS: "cannot_connect"},
             )
 
+        pin = async_get_pin_from_uid(info[CONF_UID])
+        await self._async_set_unique_id(pin)
+
         return self.async_create_entry(
-            title=info["title"], data={CONF_UID: info["uid"], **user_input}
+            title=info[CONF_UID], data={CONF_UID: info["uid"], **user_input}
         )
 
     async def async_step_zeroconf(self, discovery_info=None):
@@ -66,19 +85,20 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
         if discovery_info is None:
             return self.async_abort(reason="connection_error")
 
-        ip_address = discovery_info["host"]
+        pin = async_get_pin_from_discovery_hostname(discovery_info["hostname"])
+        await self._async_set_unique_id(pin)
 
         # pylint: disable=no-member # https://github.com/PyCQA/pylint/issues/3167
-        self.context[CONF_IP_ADDRESS] = ip_address
+        self.context[CONF_IP_ADDRESS] = discovery_info["host"]
 
         if any(
-            ip_address == flow["context"][CONF_IP_ADDRESS]
+            discovery_info["host"] == flow["context"][CONF_IP_ADDRESS]
             for flow in self._async_in_progress()
         ):
             return self.async_abort(reason="already_in_progress")
 
         self.discovery_info = {
-            CONF_IP_ADDRESS: ip_address,
+            CONF_IP_ADDRESS: discovery_info["host"],
             CONF_PORT: discovery_info["port"],
         }
 
diff --git a/tests/components/guardian/test_config_flow.py b/tests/components/guardian/test_config_flow.py
index 1625e48f1ba..8e44b9f1417 100644
--- a/tests/components/guardian/test_config_flow.py
+++ b/tests/components/guardian/test_config_flow.py
@@ -4,17 +4,21 @@ from asynctest import patch
 
 from homeassistant import data_entry_flow
 from homeassistant.components.guardian import CONF_UID, DOMAIN
+from homeassistant.components.guardian.config_flow import (
+    async_get_pin_from_discovery_hostname,
+    async_get_pin_from_uid,
+)
 from homeassistant.config_entries import SOURCE_USER, SOURCE_ZEROCONF
 from homeassistant.const import CONF_IP_ADDRESS, CONF_PORT
 
 from tests.common import MockConfigEntry
 
 
-async def test_duplicate_error(hass):
+async def test_duplicate_error(hass, ping_client):
     """Test that errors are shown when duplicate entries are added."""
     conf = {CONF_IP_ADDRESS: "192.168.1.100", CONF_PORT: 7777}
 
-    MockConfigEntry(domain=DOMAIN, unique_id="192.168.1.100", data=conf).add_to_hass(
+    MockConfigEntry(domain=DOMAIN, unique_id="guardian_3456", data=conf).add_to_hass(
         hass
     )
 
@@ -40,6 +44,18 @@ async def test_connect_error(hass):
         assert result["errors"] == {CONF_IP_ADDRESS: "cannot_connect"}
 
 
+async def test_get_pin_from_discovery_hostname():
+    """Test getting a device PIN from the zeroconf-discovered hostname."""
+    pin = async_get_pin_from_discovery_hostname("GVC1-3456.local.")
+    assert pin == "3456"
+
+
+async def test_get_pin_from_uid():
+    """Test getting a device PIN from its UID."""
+    pin = async_get_pin_from_uid("ABCDEF123456")
+    assert pin == "3456"
+
+
 async def test_step_user(hass, ping_client):
     """Test the user step."""
     conf = {CONF_IP_ADDRESS: "192.168.1.100", CONF_PORT: 7777}
@@ -54,7 +70,7 @@ async def test_step_user(hass, ping_client):
         DOMAIN, context={"source": SOURCE_USER}, data=conf
     )
     assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
-    assert result["title"] == "Elexa Guardian (192.168.1.100)"
+    assert result["title"] == "ABCDEF123456"
     assert result["data"] == {
         CONF_IP_ADDRESS: "192.168.1.100",
         CONF_PORT: 7777,
@@ -83,7 +99,7 @@ async def test_step_zeroconf(hass, ping_client):
         result["flow_id"], user_input={}
     )
     assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
-    assert result["title"] == "Elexa Guardian (192.168.1.100)"
+    assert result["title"] == "ABCDEF123456"
     assert result["data"] == {
         CONF_IP_ADDRESS: "192.168.1.100",
         CONF_PORT: 7777,