diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index d4138d93f0f748d2aeb4efee9c2cedc41bc021dc..450a0cd57f8b48eec082406925c35f65d5e457e3 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -938,6 +938,30 @@ bool cmQtAutoGenInitializer::InitScanFiles()
           if (!uicOpts.empty()) {
             this->Uic.UiFiles.emplace_back(fullPath, cmExpandedList(uicOpts));
           }
+
+          auto uiHeaderRelativePath = cmSystemTools::RelativePath(
+            this->LocalGen->GetCurrentSourceDirectory(),
+            cmSystemTools::GetFilenamePath(fullPath));
+
+          auto uiHeaderFilePath = cmStrCat(
+            '/', uiHeaderRelativePath, '/', "ui_"_s,
+            cmSystemTools::GetFilenameWithoutLastExtension(fullPath), ".h"_s);
+
+          ConfigString uiHeader;
+          uiHeader.Default =
+            cmStrCat(this->Dir.Build, "/include"_s, uiHeaderFilePath);
+          auto uiHeaderGenex = uiHeader.Default;
+          if (this->MultiConfig) {
+            uiHeaderGenex = cmStrCat(this->Dir.Build, "/include_$<CONFIG>"_s,
+                                     uiHeaderFilePath);
+            for (std::string const& cfg : this->ConfigsList) {
+              uiHeader.Config[cfg] = cmStrCat(this->Dir.Build, "/include_"_s,
+                                              cfg, uiHeaderFilePath);
+            }
+          }
+
+          this->Uic.UiHeaders.emplace_back(
+            std::make_pair(uiHeader, uiHeaderGenex));
         } else {
           // Register skipped .ui file
           this->Uic.SkipUi.insert(fullPath);
@@ -1091,6 +1115,13 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
     autogenByproducts.push_back(this->Moc.CompilationFileGenex);
   }
 
+  if (this->Uic.Enabled) {
+    for (const auto& file : this->Uic.UiHeaders) {
+      this->AddGeneratedSource(file.first, this->Uic);
+      autogenByproducts.push_back(file.second);
+    }
+  }
+
   // Compose target comment
   std::string autogenComment;
   {
diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h
index f7e126d1009428e6f5754d8cde6f2139e5bbe5e9..fdb65d3df0262d847222d3eaefc46a933d67f33d 100644
--- a/Source/cmQtAutoGenInitializer.h
+++ b/Source/cmQtAutoGenInitializer.h
@@ -239,6 +239,8 @@ private:
     std::vector<UiFileT> UiFiles;
     ConfigStrings<std::vector<std::string>> Options;
     std::vector<std::string> SearchPaths;
+    std::vector<std::pair<ConfigString /*ui header*/, std::string /*genex*/>>
+      UiHeaders;
   } Uic;
 
   /** rcc variables.  */
diff --git a/Tests/QtAutogen/RerunUicOnFileChange/CMakeLists.txt b/Tests/QtAutogen/RerunUicOnFileChange/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1f636af451fb0e5f9429478f67fbcf7ba2ba529c
--- /dev/null
+++ b/Tests/QtAutogen/RerunUicOnFileChange/CMakeLists.txt
@@ -0,0 +1,102 @@
+cmake_minimum_required(VERSION 3.17)
+project(RerunUicOnFileChange)
+include("../AutogenGuiTest.cmake")
+
+# Utility variables
+set(testProjectTemplateDir "${CMAKE_CURRENT_SOURCE_DIR}/UicOnFileChange")
+set(testProjectSrc "${CMAKE_CURRENT_BINARY_DIR}/UicOnFileChange")
+set(testProjectBinDir "${CMAKE_CURRENT_BINARY_DIR}/UicOnFileChange-build")
+
+set(TEST_CONFIG "Release")
+
+macro(sleep)
+  message(STATUS "Sleeping for a few seconds.")
+  execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
+endmacro()
+macro(rebuild buildName)
+  message(STATUS "Starting build ${buildName}.")
+  execute_process(COMMAND "${CMAKE_COMMAND}" --build . --config "${TEST_CONFIG}"
+    WORKING_DIRECTORY "${testProjectBinDir}" RESULT_VARIABLE result
+  )
+  if (result)
+    message(FATAL_ERROR "Build ${buildName} failed.")
+  else()
+    message(STATUS "Build ${buildName} finished.")
+  endif()
+endmacro()
+
+configure_file("${testProjectTemplateDir}/mocwidget.h" "${testProjectSrc}/mocwidget.h" COPYONLY)
+configure_file("${testProjectTemplateDir}/main.cpp" "${testProjectSrc}/main.cpp" COPYONLY)
+configure_file("${testProjectTemplateDir}/CMakeLists.txt.in" "${testProjectSrc}/CMakeLists.txt" @ONLY)
+
+set(Num 1)
+configure_file("${testProjectTemplateDir}/mainwindow.ui.in" "${testProjectSrc}/mainwindow.ui" @ONLY)
+
+if(CMAKE_GENERATOR_INSTANCE)
+    set(_D_CMAKE_GENERATOR_INSTANCE "-DCMAKE_GENERATOR_INSTANCE=${CMAKE_GENERATOR_INSTANCE}")
+else()
+    set(_D_CMAKE_GENERATOR_INSTANCE "")
+endif()
+
+get_property(is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(is_multi)
+  set(build_type_extra "-DCMAKE_CONFIGURATION_TYPES=${TEST_CONFIG}")
+  set(extra_bin_path "${TEST_CONFIG}/")
+else()
+  set(build_type_extra "-DCMAKE_BUILD_TYPE=${TEST_CONFIG}")
+endif()
+
+# Set the environment PATH/LD_LIBRARY_PATH variables to run the resulting executable
+if(WIN32 AND TARGET ${QT_QTCORE_TARGET})
+  get_target_property(qtcore_path ${QT_QTCORE_TARGET} LOCATION)
+  if(NOT qtcore_path)
+    get_target_property(qtcore_path ${QT_QTCORE_TARGET} IMPORTED_LOCATION)
+  endif()
+  get_filename_component(qtcore_path "${qtcore_path}" DIRECTORY)
+  set(ENV{PATH} "${qtcore_path};$ENV{PATH}")
+endif()
+
+execute_process(
+  COMMAND "${CMAKE_COMMAND}" -B "${testProjectBinDir}" -S "${testProjectSrc}"
+          -G "${CMAKE_GENERATOR}"
+          -A "${CMAKE_GENERATOR_PLATFORM}"
+          -T "${CMAKE_GENERATOR_TOOLSET}"
+          ${_D_CMAKE_GENERATOR_INSTANCE}
+          "${build_type_extra}"
+          "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
+          "-DCMAKE_AUTOGEN_VERBOSE=${CMAKE_AUTOGEN_VERBOSE}"
+          "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
+  RESULT_VARIABLE exit_code
+  OUTPUT_VARIABLE output
+  ERROR_VARIABLE output
+)
+if(NOT exit_code EQUAL 0)
+  message(FATAL_ERROR "Initial configuration of UicOnFileChange failed. Output: ${output}")
+endif()
+
+# Initial build
+execute_process(
+    COMMAND "${CMAKE_COMMAND}" --build "${testProjectBinDir}" --config "${TEST_CONFIG}"
+    RESULT_VARIABLE exit_code
+    OUTPUT_VARIABLE output
+    ERROR_VARIABLE output
+)
+if(NOT exit_code EQUAL 0)
+    message(FATAL_ERROR "Initial build of UicOnFileChange failed. Output: ${output}")
+endif()
+
+execute_process(COMMAND "${testProjectBinDir}/${extra_bin_path}UicOnFileChange" RESULT_VARIABLE result)
+if(NOT result EQUAL "1")
+  message(FATAL_ERROR "Initial build of UicOnFileChange test result is: ${result}")
+endif()
+
+sleep()
+
+set(Num 2)
+configure_file("${testProjectTemplateDir}/mainwindow.ui.in" "${testProjectSrc}/mainwindow.ui" @ONLY)
+rebuild(2)
+
+execute_process(COMMAND "${testProjectBinDir}/${extra_bin_path}UicOnFileChange" RESULT_VARIABLE result)
+if(NOT result EQUAL "0")
+  message(FATAL_ERROR "Rebuild of UicOnFileChange test result is: ${result}")
+endif()
diff --git a/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/CMakeLists.txt.in b/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/CMakeLists.txt.in
new file mode 100644
index 0000000000000000000000000000000000000000..fa9dd6bee3239b01ea10450191c6bfe00500e294
--- /dev/null
+++ b/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/CMakeLists.txt.in
@@ -0,0 +1,11 @@
+cmake_minimum_required(VERSION 3.10)
+
+project(UicOnFileChange)
+include("@CMAKE_CURRENT_LIST_DIR@/../AutogenGuiTest.cmake")
+
+# Enable CMAKE_AUTOUIC for all targets
+set(CMAKE_AUTOUIC ON)
+
+add_executable(UicOnFileChange main.cpp mainwindow.ui)
+target_include_directories(UicOnFileChange PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+target_link_libraries(UicOnFileChange ${QT_QTCORE_TARGET} ${QT_LIBRARIES})
diff --git a/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/main.cpp b/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fd810fa24727e4f2880d0bb9c589a4c3f1621667
--- /dev/null
+++ b/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/main.cpp
@@ -0,0 +1,9 @@
+#include "ui_mainwindow.h"
+
+int main(int argc, char* argv[])
+{
+  MocWidget mw;
+  Ui::Widget mwUi;
+  mwUi.setupUi(&mw);
+  return mw.objectName() == "Widget2" ? 0 : 1;
+}
diff --git a/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/mainwindow.ui.in b/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/mainwindow.ui.in
new file mode 100644
index 0000000000000000000000000000000000000000..8f39e5514c21d49e894a245a0d49609485d54656
--- /dev/null
+++ b/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/mainwindow.ui.in
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Widget</class>
+ <widget class="MocWidget" name="Widget@Num@"/>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/mocwidget.h b/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/mocwidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..87fc177ddfb257d16c0e94b290f2b03d57b3b10c
--- /dev/null
+++ b/Tests/QtAutogen/RerunUicOnFileChange/UicOnFileChange/mocwidget.h
@@ -0,0 +1,5 @@
+#include <QtCore/QObject>
+
+class MocWidget : public QObject
+{
+};
diff --git a/Tests/QtAutogen/Tests.cmake b/Tests/QtAutogen/Tests.cmake
index b1337d6266cf60fa6fdbe93803576ff54c992280..d1edd72f4f30dfa32362dc7c9f9f5027a3745346 100644
--- a/Tests/QtAutogen/Tests.cmake
+++ b/Tests/QtAutogen/Tests.cmake
@@ -24,6 +24,7 @@ ADD_AUTOGEN_TEST(RerunMocOnAddFile)
 ADD_AUTOGEN_TEST(RerunMocOnMissingDependency)
 ADD_AUTOGEN_TEST(RerunRccConfigChange)
 ADD_AUTOGEN_TEST(RerunRccDepends)
+ADD_AUTOGEN_TEST(RerunUicOnFileChange)
 ADD_AUTOGEN_TEST(SameName sameName)
 ADD_AUTOGEN_TEST(StaticLibraryCycle slc)
 ADD_AUTOGEN_TEST(UicInclude uicInclude)