diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 869cae81bd..3350af0252 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -819,6 +819,7 @@ function install_tasks($install_state) {
       'run' => $needs_translations ? INSTALL_TASK_RUN_IF_NOT_COMPLETED : INSTALL_TASK_SKIP,
     ],
     'install_finished' => [],
+    'install_invoke_finished_hooks' => [],
   ];
 
   // Allow the installation profile to modify the full list of tasks.
@@ -1796,6 +1797,16 @@ function install_finished(&$install_state) {
 }
 
 /**
+ * Invokes hooks related to site installation being finished.
+ *
+ * @param $install_state
+ *   An array of information about the current installation state.
+ */
+function install_invoke_finished_hooks(&$install_state) {
+  \Drupal::moduleHandler()->invokeAll('site_install_finished', $install_state);
+}
+
+/**
  * Implements callback_batch_operation().
  *
  * Performs batch installation of modules.
diff --git a/core/lib/Drupal/Core/Extension/module.api.php b/core/lib/Drupal/Core/Extension/module.api.php
index 1762752364..7e125088ed 100644
--- a/core/lib/Drupal/Core/Extension/module.api.php
+++ b/core/lib/Drupal/Core/Extension/module.api.php
@@ -477,6 +477,23 @@ function hook_install_tasks_alter(&$tasks, $install_state) {
 }
 
 /**
+ * Responds to Drupal being installed.
+ *
+ * @param $install_state
+ *   An array of information about the current installation state.
+ *
+ * @see install_tasks()
+ */
+function hook_site_install_finished($install_state) {
+  if (!empty($install_state['parameters']['profile'])) {
+    $profile = $install_state['parameters']['profile'];
+    if ($profile === 'special_profile') {
+      \Drupal::state()->set('my_module_special_profile_support', TRUE);
+    }
+  }
+}
+
+/**
  * Perform a single update between minor versions.
  *
  * hook_update_N() can only be used to update between minor versions of a
