diff --git a/core/includes/common.inc b/core/includes/common.inc
index aff7665..e59526c 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -286,6 +286,26 @@ function drupal_get_profile() {
 }

 /**
+ * Returns a list of related installation profiles in descending order of their
+ * dependencies.
+ */
+function drupal_get_profiles($profile) {
+  if (!function_exists('install_get_base_profiles')) {
+    require_once DRUPAL_ROOT . '/core/includes/install.inc';
+  }
+
+  $profiles = array();
+
+  if (!empty($profile)) {
+    $profiles = array_reverse(install_get_base_profiles($profile));
+    $profiles[] = $profile;
+  }
+
+  return $profiles;
+}
+
+
+/**
  * Adds output to the HEAD tag of the HTML page.
  *
  * This function can be called as long as the headers aren't sent. Pass no
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index b44c59a..1cd8238 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -199,6 +199,9 @@ function install_state_defaults() {
     // An array of information about the chosen installation profile. This will
     // be filled in based on the profile's .info.yml file.
     'profile_info' => array(),
+    // An array of information for each of the base profiles of the chosen
+    // installation profile.
+    'base_profiles_info' => array(),
     // An array of available installation profiles.
     'profiles' => array(),
     // An array of server variables that will be substituted into the global
@@ -843,16 +846,17 @@ function install_tasks($install_state) {
   if (!empty($install_state['parameters']['profile'])) {
     // Load the profile install file, because it is not always loaded when
     // hook_install_tasks() is invoked (e.g. batch processing).
-    $profile = $install_state['parameters']['profile'];
-    $profile_install_file = dirname($install_state['profiles'][$profile]->uri) . '/' . $profile . '.install';
-    if (file_exists($profile_install_file)) {
-      include_once DRUPAL_ROOT . '/' . $profile_install_file;
-    }
-    $function = $install_state['parameters']['profile'] . '_install_tasks';
-    if (function_exists($function)) {
-      $result = $function($install_state);
-      if (is_array($result)) {
-        $tasks += $result;
+    foreach (drupal_get_profiles($install_state['parameters']['profile']) as $profile) {
+      $profile_install_file = dirname($install_state['profiles'][$profile]->uri). '/' . $profile . '.install';
+      if (file_exists($profile_install_file)) {
+        include_once $profile_install_file;
+      }
+      $function = $profile . '_install_tasks';
+      if (function_exists($function)) {
+        $result = $function($install_state);
+        if (is_array($result)) {
+          $tasks += $result;
+        }
       }
     }
   }
@@ -878,13 +882,14 @@ function install_tasks($install_state) {

   // Allow the installation profile to modify the full list of tasks.
   if (!empty($install_state['parameters']['profile'])) {
-    $profile = $install_state['parameters']['profile'];
-    $profile_file = $install_state['profiles'][$profile]->uri;
-    if (file_exists($profile_file)) {
-      include_once DRUPAL_ROOT . '/' .  $profile_file;
-      $function = $install_state['parameters']['profile'] . '_install_tasks_alter';
-      if (function_exists($function)) {
-        $function($tasks, $install_state);
+    foreach (drupal_get_profiles($install_state['parameters']['profile']) as $profile) {
+      $profile_file = $install_state['profiles'][$profile]->uri;
+      if (file_exists($profile_file)) {
+        include_once $profile_file;
+        $function = $profile . '_install_tasks_alter';
+        if (function_exists($function)) {
+          $function($tasks, $install_state);
+        }
       }
     }
   }
@@ -1046,11 +1051,19 @@ function install_base_system(&$install_state) {

   // Save the list of other modules to install for the upcoming tasks.
   // State can be set to the database now that system.module is installed.
-  $modules = $install_state['profile_info']['dependencies'];
+  $profiles = drupal_get_profiles($install_state['parameters']['profile']);
+  $profile_dependencies = array();
+
+  foreach ($profiles as $profile) {
+    $info = install_profile_info($profile);
+    $profile_dependencies = array_unique(array_merge($profile_dependencies, $info['dependencies']));
+  }
+
+  $modules = $profile_dependencies;

   // The installation profile is also a module, which needs to be installed
   // after all the dependencies have been installed.
-  $modules[] = drupal_get_profile();
+  $modules = array_merge($modules, $profiles);

   \Drupal::state()->set('install_profile_modules', array_diff($modules, array('system')));
   $install_state['database_tables_exist'] = TRUE;
@@ -1913,14 +1926,21 @@ function install_already_done_error() {
  *   the profile cannot be loaded.
  */
 function install_load_profile(&$install_state) {
-  $profile = $install_state['parameters']['profile'];
-  $profile_file = $install_state['profiles'][$profile]->uri;
-  if (file_exists($profile_file)) {
-    include_once DRUPAL_ROOT . '/' . $profile_file;
-    $install_state['profile_info'] = install_profile_info($install_state['parameters']['profile'], $install_state['parameters']['langcode']);
-  }
-  else {
-    throw new Exception(t('Sorry, the profile you have chosen cannot be loaded.'));
+  foreach (drupal_get_profiles($install_state['parameters']['profile']) as $profile) {
+    $profile_file = $install_state['profiles'][$profile]->uri;
+    if (file_exists($profile_file)) {
+      include_once $profile_file;
+
+      if ($profile == $install_state['parameters']['profile']) {
+        $install_state['profile_info'] = install_profile_info($profile, $install_state['parameters']['langcode']);
+      }
+      else {
+       $install_state['base_profiles_info'][] = install_profile_info($profile, $install_state['parameters']['langcode']);
+      }
+    }
+    else {
+      throw new Exception(t('Sorry, the profile you have chosen cannot be loaded.'));
+    }
   }
 }

@@ -1957,7 +1977,9 @@ function install_profile_modules(&$install_state) {
   // Although the profile module is marked as required, it needs to go after
   // every dependency, including non-required ones. So clear its required
   // flag for now to allow it to install late.
-  $files[$install_state['parameters']['profile']]->info['required'] = FALSE;
+  foreach (drupal_get_profiles($install_state['parameters']['profile']) as $profile) {
+    $files[$profile]->info['required'] = FALSE;
+  }
   // Add modules that other modules depend on.
   foreach ($modules as $module) {
     if ($files[$module]->requires) {
diff --git a/core/includes/install.inc b/core/includes/install.inc
index 256c79e..09d6601 100644
--- a/core/includes/install.inc
+++ b/core/includes/install.inc
@@ -569,10 +569,23 @@ function drupal_verify_profile($install_state) {
   include_once __DIR__ . '/file.inc';
   include_once __DIR__ . '/common.inc';

-  $profile = $install_state['parameters']['profile'];
-  $profile_file = $install_state['profiles'][$profile]->uri;
+  $selected_profile = $install_state['parameters']['profile'];
+  $profiles = drupal_get_profiles($selected_profile);

-  if (!isset($profile) || !file_exists($profile_file)) {
+  if (!empty($profiles)) {
+    $profile_dependencies = array();
+
+    foreach ($profiles as $profile) {
+      $profile_file = $install_state['profiles'][$profile]->uri;
+
+      if (!file_exists($profile_file)) {
+        throw new Exception(install_no_profile_error());
+      }
+      $info = install_profile_info($profile);
+      $profile_dependencies = array_unique(array_merge($profile_dependencies, $info['dependencies']));
+    }
+  }
+  else {
     throw new Exception(install_no_profile_error());
   }
   $info = $install_state['profile_info'];
@@ -585,10 +598,10 @@ function drupal_verify_profile($install_state) {

   // The installation profile is also a module, which needs to be installed
   // after all the other dependencies have been installed.
-  $present_modules[] = drupal_get_profile();
+  $present_modules = array_merge($present_modules, $profiles);

   // Verify that all of the profile's required modules are present.
-  $missing_modules = array_diff($info['dependencies'], $present_modules);
+  $missing_modules = array_diff($profile_dependencies, $present_modules);

   $requirements = array();

@@ -951,23 +964,33 @@ function drupal_requirements_url($severity) {
 function drupal_check_profile($profile, array $install_state) {
   include_once __DIR__ . '/file.inc';

-  $profile_file = $install_state['profiles'][$profile]->uri;
-
-  if (!isset($profile) || !file_exists($profile_file)) {
-    throw new Exception(install_no_profile_error());
-  }
+  $requirements = array();
+  if (isset($profile)) {
+    $profile_dependencies = array();

-  $info = install_profile_info($profile);
+    // Loop through all active installation profiles to collect dependencies.
+    foreach (drupal_get_profiles($profile) as $profile) {
+      $profile_file = $install_state['profiles'][$profile]->uri;

-  // Collect requirement testing results.
-  $requirements = array();
-  foreach ($info['dependencies'] as $module) {
-    module_load_install($module);
-    $function = $module . '_requirements';
-    if (function_exists($function)) {
-      $requirements = array_merge($requirements, $function('install'));
+      if (!file_exists($profile_file)) {
+        throw new Exception(install_no_profile_error());
+      }
+      $info = install_profile_info($profile);
+      $profile_dependencies = array_unique(array_merge($profile_dependencies, $info['dependencies']));
+    }
+    // Collect requirement testing results.
+    foreach ($profile_dependencies as $module) {
+      module_load_install($module);
+      $function = $module . '_requirements';
+      if (function_exists($function)) {
+        $requirements = array_merge($requirements, $function('install'));
+      }
     }
   }
+  else {
+    throw new Exception(install_no_profile_error());
+  }
+
   return $requirements;
 }

@@ -1095,6 +1118,31 @@ function install_profile_info($profile, $langcode = 'en') {
 }

 /**
+ * + * Returns a list of base installation profiles associated with the specified
+ * installation profile.
+ *
+ * @return
+ *   An array of profile names. An empty array if installation profile has no
+ *   parent profiles.
+ */
+function install_get_base_profiles($profile) {
+  $cache = &drupal_static(__FUNCTION__, array());
+
+  if (!isset($cache[$profile])) {
+    $profile_file = drupal_get_path('profile', $profile) . "/$profile.info.yml";
+    $info = drupal_parse_info_file($profile_file);
+    $cache[$profile] = array();
+
+    while (!empty($info) && isset($info['base'])) {
+      $cache[$profile][] = $info['base'];
+      $info = install_profile_info($info['base']);
+    }
+  }
+
+  return $cache[$profile];
+}
+
+/**
  * Ensures the environment for a Drupal database on a predefined connection.
  *
  * This will run tasks that check that Drupal can perform all of the functions
diff --git a/core/includes/module.inc b/core/includes/module.inc
index 429f5db..119ae20 100644
--- a/core/includes/module.inc
+++ b/core/includes/module.inc
@@ -289,7 +289,7 @@ function drupal_required_modules() {
   $required = array();

   // An installation profile is required and one must always be loaded.
-  $required[] = drupal_get_profile();
+  $required = array_merge($required, drupal_get_profiles(drupal_get_profile()));

   foreach ($files as $name => $file) {
     $info = \Drupal::service('info_parser')->parse($file->uri);
diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php
index 92cf2a4..b01e180 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandler.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php
@@ -693,7 +693,7 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE) {
           }

           // Skip already uninstalled modules.
-          if (isset($installed_modules[$dependent]) && !isset($module_list[$dependent]) && $dependent != $profile) {
+          if (isset($installed_modules[$dependent]) && !isset($module_list[$dependent]) && !in_array($dependent, $profiles)) {
             $module_list[$dependent] = TRUE;
           }
         }
diff --git a/core/modules/system/lib/Drupal/system/Form/ModulesUninstallForm.php b/core/modules/system/lib/Drupal/system/Form/ModulesUninstallForm.php
index 711f934..0fb87a4 100644
--- a/core/modules/system/lib/Drupal/system/Form/ModulesUninstallForm.php
+++ b/core/modules/system/lib/Drupal/system/Form/ModulesUninstallForm.php
@@ -82,7 +82,7 @@ public function buildForm(array $form, array &$form_state) {
       return $form;
     }

-    $profile = drupal_get_profile();
+    $profiles = drupal_get_profiles(drupal_get_profile());

     // Sort all modules by their name.
     $this->moduleHandler->loadInclude('system', 'inc', 'system.admin');
@@ -105,7 +105,7 @@ public function buildForm(array $form, array &$form_state) {
       // we can allow this module to be uninstalled. (The installation profile
       // is excluded from this list.)
       foreach (array_keys($module->required_by) as $dependent) {
-        if ($dependent != $profile && drupal_get_installed_schema_version($dependent) != SCHEMA_UNINSTALLED) {
+        if (!in_array($dependent, $profiles) && drupal_get_installed_schema_version($dependent) != SCHEMA_UNINSTALLED) {
           $name = isset($modules[$dependent]->info['name']) ? $modules[$dependent]->info['name'] : $dependent;
           $form['modules'][$module->name]['#required_by'][] = $name;
           $form['uninstall'][$module->name]['#disabled'] = TRUE;
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 14153a0..d36d0a9 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -453,11 +453,11 @@ function system_requirements($phase) {

   // Display an error if a newly introduced dependency in a module is not resolved.
   if ($phase == 'update') {
-    $profile = drupal_get_profile();
+    $profile =  drupal_get_profiles(drupal_get_profile());
     $files = system_rebuild_module_data();
     foreach ($files as $module => $file) {
       // Ignore disabled modules and installation profiles.
-      if (!$file->status || $module == $profile) {
+      if (!$file->status || in_array($module, $profiles)) {
         continue;
       }
       // Check the module's PHP version.
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index d922cd9..da1a47a 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -2332,12 +2332,17 @@ function _system_rebuild_module_data() {
   // Find installation profiles.
   $profiles = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles', 'name', 0);

-  // Include the installation profile in modules that are loaded.
-  $profile = drupal_get_profile();
-  $modules[$profile] = $profiles[$profile];
+  // Include the active installation profile(s) in modules that are loaded.
+  $profile_weight = 1000;
+  $base_profiles = drupal_get_profiles(drupal_get_profile());

   // Installation profile hooks are always executed last.
-  $modules[$profile]->weight = 1000;
+  foreach ($base_profiles as $profile) {
+    $modules[$profile] = $profiles[$profile];
+
+    // Installation profile hooks are always executed last.
+    $modules[$profile]->weight = $profile_weight++;
+  }

   // Set defaults for module info.
   $defaults = array(
@@ -2383,13 +2388,15 @@ function _system_rebuild_module_data() {
     drupal_alter('system_info', $modules[$key]->info, $modules[$key], $type);
   }

-  if (isset($modules[$profile])) {
-    // The installation profile is required, if it's a valid module.
-    $modules[$profile]->info['required'] = TRUE;
-    // Add a default distribution name if the profile did not provide one. This
-    // matches the default value used in install_profile_info().
-    if (!isset($modules[$profile]->info['distribution_name'])) {
-      $modules[$profile]->info['distribution_name'] = 'Drupal';
+  foreach ($base_profiles as $profile) {
+    if (isset($modules[$profile])) {
+      // The installation profile is required, if it's a valid module.
+      $modules[$profile]->info['required'] = TRUE;
+      // Add a default distribution name if the profile did not provide one.
+      // This matches the default value used in install_profile_info().
+      if (in_array($key, $profiles) && !isset($modules[$key]->info['hidden'])) {
+        $modules[$profile]->info['distribution_name'] = 'Drupal';
+      }
     }
   }
