diff --git a/homeassistant/components/update/__init__.py b/homeassistant/components/update/__init__.py
index 8d4a5614f94f3d740d0b0c0a7e1a55f999352cd7..e308365c1c67c10909520eeda0bf23244b36cb7f 100644
--- a/homeassistant/components/update/__init__.py
+++ b/homeassistant/components/update/__init__.py
@@ -197,6 +197,7 @@ CACHED_PROPERTIES_WITH_ATTR_ = {
     "release_url",
     "supported_features",
     "title",
+    "update_percentage",
 }
 
 
@@ -227,6 +228,7 @@ class UpdateEntity(
     _attr_state: None = None
     _attr_supported_features: UpdateEntityFeature = UpdateEntityFeature(0)
     _attr_title: str | None = None
+    _attr_update_percentage: int | None = None
     __skipped_version: str | None = None
     __in_progress: bool = False
 
@@ -284,8 +286,7 @@ class UpdateEntity(
 
         Needs UpdateEntityFeature.PROGRESS flag to be set for it to be used.
 
-        Can either return a boolean (True if in progress, False if not)
-        or an integer to indicate the progress in from 0 to 100%.
+        Should return a boolean (True if in progress, False if not).
         """
         return self._attr_in_progress
 
@@ -335,6 +336,16 @@ class UpdateEntity(
             return new_features
         return features
 
+    @cached_property
+    def update_percentage(self) -> int | None:
+        """Update installation progress.
+
+        Needs UpdateEntityFeature.PROGRESS flag to be set for it to be used.
+
+        Can either return an integer to indicate the progress from 0 to 100% or None.
+        """
+        return self._attr_update_percentage
+
     @final
     async def async_skip(self) -> None:
         """Skip the current offered version to update."""
@@ -424,17 +435,17 @@ class UpdateEntity(
         if (release_summary := self.release_summary) is not None:
             release_summary = release_summary[:255]
 
-        update_percentage = None
-
         # If entity supports progress, return the in_progress value.
         # Otherwise, we use the internal progress value.
         if UpdateEntityFeature.PROGRESS in self.supported_features_compat:
             in_progress = self.in_progress
+            update_percentage = self.update_percentage
+            if type(in_progress) is not bool and isinstance(in_progress, int):
+                update_percentage = in_progress
+                in_progress = True
         else:
             in_progress = self.__in_progress
-        if type(in_progress) is not bool and isinstance(in_progress, int):
-            update_percentage = in_progress
-            in_progress = True
+            update_percentage = None
 
         installed_version = self.installed_version
         latest_version = self.latest_version
diff --git a/tests/components/update/common.py b/tests/components/update/common.py
index 70b69498f666f57b2625331dc1b0a32f84e20ec2..edbade8f0776e2b862c97ceb37050490fb6b9bb4 100644
--- a/tests/components/update/common.py
+++ b/tests/components/update/common.py
@@ -48,6 +48,11 @@ class MockUpdateEntity(MockEntity, UpdateEntity):
         """Title of the software."""
         return self._handle("title")
 
+    @property
+    def update_percentage(self) -> int | None:
+        """Update installation progress."""
+        return self._handle("update_percentage")
+
     def install(self, version: str | None, backup: bool, **kwargs: Any) -> None:
         """Install an update."""
         if backup:
diff --git a/tests/components/update/conftest.py b/tests/components/update/conftest.py
index 759f243e8db7a6df743794ab5d012eb60538f32d..4fc2a68221e74f805a84f48dfe5a3065e02d1f0a 100644
--- a/tests/components/update/conftest.py
+++ b/tests/components/update/conftest.py
@@ -54,9 +54,10 @@ def mock_update_entities() -> list[MockUpdateEntity]:
             unique_id="update_already_in_progres",
             installed_version="1.0.0",
             latest_version="1.0.1",
-            in_progress=50,
+            in_progress=True,
             supported_features=UpdateEntityFeature.INSTALL
             | UpdateEntityFeature.PROGRESS,
+            update_percentage=50,
         ),
         MockUpdateEntity(
             name="Update No Install",