diff --git a/.coveragerc b/.coveragerc
index f4794b593816f112c19e4715cb311dd49d1472ee..c6e7182d326d8866c28a5f46d0c22f1f6ba5a53e 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -321,6 +321,7 @@ omit =
     homeassistant/components/iaqualink/switch.py
     homeassistant/components/icloud/__init__.py
     homeassistant/components/icloud/device_tracker.py
+    homeassistant/components/icloud/sensor.py
     homeassistant/components/izone/climate.py
     homeassistant/components/izone/discovery.py
     homeassistant/components/izone/__init__.py
diff --git a/homeassistant/components/icloud/__init__.py b/homeassistant/components/icloud/__init__.py
index 2012f69193803b3dec2ce504a4c3fbbbce40b21d..c59f4098951ad35b5d9133d5188ec89d6c552d4b 100644
--- a/homeassistant/components/icloud/__init__.py
+++ b/homeassistant/components/icloud/__init__.py
@@ -560,11 +560,6 @@ class IcloudDevice:
         """Return a unique ID."""
         return self._device_id
 
-    @property
-    def dev_id(self) -> str:
-        """Return the device ID."""
-        return self._device_id
-
     @property
     def name(self) -> str:
         """Return the Apple device name."""
diff --git a/homeassistant/components/icloud/const.py b/homeassistant/components/icloud/const.py
index 4e99a378077c9a727cdb7ae128ce71d87bde3718..ed2fc78fe6d25401dd566f765f8e2ccde1f9b1f1 100644
--- a/homeassistant/components/icloud/const.py
+++ b/homeassistant/components/icloud/const.py
@@ -14,8 +14,7 @@ DEFAULT_GPS_ACCURACY_THRESHOLD = 500  # meters
 STORAGE_KEY = DOMAIN
 STORAGE_VERSION = 1
 
-# Next PR will add sensor
-ICLOUD_COMPONENTS = ["device_tracker"]
+ICLOUD_COMPONENTS = ["device_tracker", "sensor"]
 
 # pyicloud.AppleDevice status
 DEVICE_BATTERY_LEVEL = "batteryLevel"
diff --git a/homeassistant/components/icloud/device_tracker.py b/homeassistant/components/icloud/device_tracker.py
index 4be34728c6dfde5efa4ecaaa8df64c967abb545b..511ce7f94470a2692930fe9a2d50c281c92fb7ce 100644
--- a/homeassistant/components/icloud/device_tracker.py
+++ b/homeassistant/components/icloud/device_tracker.py
@@ -1,8 +1,10 @@
 """Support for tracking for iCloud devices."""
 import logging
+from typing import Dict
 
 from homeassistant.components.device_tracker import SOURCE_TYPE_GPS
 from homeassistant.components.device_tracker.config_entry import TrackerEntity
+from homeassistant.config_entries import ConfigEntry
 from homeassistant.const import CONF_USERNAME
 from homeassistant.helpers.dispatcher import async_dispatcher_connect
 from homeassistant.helpers.typing import HomeAssistantType
@@ -26,13 +28,15 @@ async def async_setup_scanner(
     pass
 
 
-async def async_setup_entry(hass: HomeAssistantType, entry, async_add_entities):
+async def async_setup_entry(
+    hass: HomeAssistantType, entry: ConfigEntry, async_add_entities
+):
     """Configure a dispatcher connection based on a config entry."""
     username = entry.data[CONF_USERNAME]
 
     for device in hass.data[DOMAIN][username].devices.values():
         if device.location is None:
-            _LOGGER.debug("No position found for device %s", device.name)
+            _LOGGER.debug("No position found for %s", device.name)
             continue
 
         _LOGGER.debug("Adding device_tracker for %s", device.name)
@@ -49,12 +53,12 @@ class IcloudTrackerEntity(TrackerEntity):
         self._unsub_dispatcher = None
 
     @property
-    def unique_id(self):
+    def unique_id(self) -> str:
         """Return a unique ID."""
-        return f"{self._device.unique_id}_tracker"
+        return self._device.unique_id
 
     @property
-    def name(self):
+    def name(self) -> str:
         """Return the name of the device."""
         return self._device.name
 
@@ -74,36 +78,36 @@ class IcloudTrackerEntity(TrackerEntity):
         return self._device.location[DEVICE_LOCATION_LONGITUDE]
 
     @property
-    def should_poll(self):
+    def should_poll(self) -> bool:
         """No polling needed."""
         return False
 
     @property
-    def battery_level(self):
+    def battery_level(self) -> int:
         """Return the battery level of the device."""
         return self._device.battery_level
 
     @property
-    def source_type(self):
+    def source_type(self) -> str:
         """Return the source type, eg gps or router, of the device."""
         return SOURCE_TYPE_GPS
 
     @property
-    def icon(self):
+    def icon(self) -> str:
         """Return the icon."""
         return icon_for_icloud_device(self._device)
 
     @property
-    def device_state_attributes(self):
+    def device_state_attributes(self) -> Dict[str, any]:
         """Return the device state attributes."""
         return self._device.state_attributes
 
     @property
-    def device_info(self):
+    def device_info(self) -> Dict[str, any]:
         """Return the device information."""
         return {
-            "identifiers": {(DOMAIN, self.unique_id)},
-            "name": self.name,
+            "identifiers": {(DOMAIN, self._device.unique_id)},
+            "name": self._device.name,
             "manufacturer": "Apple",
             "model": self._device.device_model,
         }
diff --git a/homeassistant/components/icloud/sensor.py b/homeassistant/components/icloud/sensor.py
new file mode 100644
index 0000000000000000000000000000000000000000..4351d4ffa1983cd3a1a3fd1808dc7413b546d4f4
--- /dev/null
+++ b/homeassistant/components/icloud/sensor.py
@@ -0,0 +1,85 @@
+"""Support for iCloud sensors."""
+import logging
+from typing import Dict
+
+from homeassistant.config_entries import ConfigEntry
+from homeassistant.const import CONF_USERNAME, DEVICE_CLASS_BATTERY
+from homeassistant.helpers.entity import Entity
+from homeassistant.helpers.icon import icon_for_battery_level
+from homeassistant.helpers.typing import HomeAssistantType
+
+from . import IcloudDevice
+from .const import DOMAIN
+
+_LOGGER = logging.getLogger(__name__)
+
+
+async def async_setup_entry(
+    hass: HomeAssistantType, entry: ConfigEntry, async_add_entities
+) -> None:
+    """Set up iCloud devices sensors based on a config entry."""
+    username = entry.data[CONF_USERNAME]
+
+    entities = []
+    for device in hass.data[DOMAIN][username].devices.values():
+        if device.battery_level is not None:
+            _LOGGER.debug("Adding battery sensor for %s", device.name)
+            entities.append(IcloudDeviceBatterySensor(device))
+
+    async_add_entities(entities, True)
+
+
+class IcloudDeviceBatterySensor(Entity):
+    """Representation of a iCloud device battery sensor."""
+
+    def __init__(self, device: IcloudDevice):
+        """Initialize the battery sensor."""
+        self._device = device
+
+    @property
+    def unique_id(self) -> str:
+        """Return a unique ID."""
+        return f"{self._device.unique_id}_battery"
+
+    @property
+    def name(self) -> str:
+        """Sensor name."""
+        return f"{self._device.name} battery state"
+
+    @property
+    def device_class(self) -> str:
+        """Return the device class of the sensor."""
+        return DEVICE_CLASS_BATTERY
+
+    @property
+    def state(self) -> int:
+        """Battery state percentage."""
+        return self._device.battery_level
+
+    @property
+    def unit_of_measurement(self) -> str:
+        """Battery state measured in percentage."""
+        return "%"
+
+    @property
+    def icon(self) -> str:
+        """Battery state icon handling."""
+        return icon_for_battery_level(
+            battery_level=self._device.battery_level,
+            charging=self._device.battery_status == "Charging",
+        )
+
+    @property
+    def device_state_attributes(self) -> Dict[str, any]:
+        """Return default attributes for the iCloud device entity."""
+        return self._device.state_attributes
+
+    @property
+    def device_info(self) -> Dict[str, any]:
+        """Return the device information."""
+        return {
+            "identifiers": {(DOMAIN, self._device.unique_id)},
+            "name": self._device.name,
+            "manufacturer": "Apple",
+            "model": self._device.device_model,
+        }