diff --git a/core/includes/config.inc b/core/includes/config.inc
index 8166e84..5c05fc2 100644
--- a/core/includes/config.inc
+++ b/core/includes/config.inc
@@ -20,8 +20,16 @@
  *   The extension type; e.g., 'module' or 'theme'.
  * @param string $name
  *   The name of the module or theme to install default configuration for.
++ * @param $overwrite_config
++ *   If FALSE (default), the default configuration for this extension will not
++ *   replace any existing configuration. Any current configuration which
++ *   overlaps with the default values provided by the extensino will be left
++ *   intact.
++ *   If TRUE, the default configuration for this extension will be merged into
++ *   any existing configuration, allowing the extension to overwrite current
++ *   configuration. This normally only applies to installation profiles.
  */
-function config_install_default_config($type, $name) {
+function config_install_default_config($type, $name, $overwrite_config = FALSE) {
   $config_dir = drupal_get_path($type, $name) . '/config';
   if (is_dir($config_dir)) {
     $source_storage = new FileStorage($config_dir);
@@ -29,12 +37,17 @@ function config_install_default_config($type, $name) {
     // Only import new config. Changed config is from previous enables and
     // should not be overwritten.
     $storage_comparer->addChangelistCreate();
+    if ($overwrite_config) {
+      // Allow the extension to change existing configuration.
+      $storage_comparer->addChangelistUpdate();
+    }
     $installer = new ConfigInstaller(
       $storage_comparer,
       Drupal::service('event_dispatcher'),
       Drupal::service('config.factory'),
       Drupal::entityManager(),
-      Drupal::lock()
+      Drupal::lock(),
+      $overwrite_config
     );
     $installer->import();
   }
@@ -46,7 +59,7 @@ function config_install_default_config($type, $name) {
  * @param string $type
  *   The extension type; e.g., 'module' or 'theme'.
  * @param string $name
- *   The name of the module or theme to install default configuration for.
+ *   The name of the module or theme to uninstall default configuration for.
  */
 function config_uninstall_default_config($type, $name) {
   $storage = drupal_container()->get('config.storage');
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 86fe8c6..067a57f 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -2036,8 +2036,9 @@ function _install_module_batch($module, $module_name, &$context) {
   // Install and enable the module right away, so that the module will be
   // loaded by drupal_bootstrap in subsequent batch requests, and other
   // modules possibly depending on it can safely perform their installation
-  // steps.
-  module_enable(array($module), FALSE);
+  // steps. If we are enabling the install profile we should allow it to
+  // overwrite configuration from other modules too.
+  Drupal::moduleHandler()->enable(array($module), FALSE, ($module == drupal_get_profile()));
   $context['results'][] = $module;
   $context['message'] = t('Installed %module module.', array('%module' => $module_name));
 }
diff --git a/core/lib/Drupal/Core/Config/ConfigImporter.php b/core/lib/Drupal/Core/Config/ConfigImporter.php
index d496fe7..4df61d8 100644
--- a/core/lib/Drupal/Core/Config/ConfigImporter.php
+++ b/core/lib/Drupal/Core/Config/ConfigImporter.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Config\Context\FreeConfigContext;
 use Drupal\Core\Entity\EntityManager;
 use Drupal\Core\Lock\LockBackendInterface;
+use Drupal\Component\Utility\NestedArray;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 
 /**
@@ -106,15 +107,19 @@ class ConfigImporter {
    *   The config factory that statically caches config objects.
    * @param \Drupal\Core\Entity\EntityManager $entity_manager
    *   The entity manager used to import config entities.
-   * @param \Drupal\Core\Lock\LockBackendInterface
+   * @param \Drupal\Core\Lock\LockBackendInterface $lock
    *   The lock backend to ensure multiple imports do not occur at the same time.
+   * @param bool $merge_on_import
+   *   (optional) Whether to merge changes into the existing configs rather
+   *   than overwriting them. Defaults to FALSE.
    */
-  public function __construct(StorageComparerInterface $storage_comparer, EventDispatcherInterface $event_dispatcher, ConfigFactory $config_factory, EntityManager $entity_manager, LockBackendInterface $lock) {
+  public function __construct(StorageComparerInterface $storage_comparer, EventDispatcherInterface $event_dispatcher, ConfigFactory $config_factory, EntityManager $entity_manager, LockBackendInterface $lock, $merge_on_import = FALSE) {
     $this->storageComparer = $storage_comparer;
     $this->eventDispatcher = $event_dispatcher;
     $this->configFactory = $config_factory;
     $this->entityManager = $entity_manager;
     $this->lock = $lock;
+    $this->mergeOnImport = $merge_on_import;
     $this->processed = $this->storageComparer->getEmptyChangelist();
     // Use an override free context for importing so that overrides to do not
     // pollute the imported data. The context is hard coded to ensure this is
@@ -259,6 +264,11 @@ protected function importConfig() {
         }
         else {
           $data = $this->storageComparer->getSourceStorage()->read($name);
+          if ($this->mergeOnImport && $op == 'update') {
+            // Merge new data into the existing configuration.
+            $existing_data = $this->storageComparer->getTargetStorage()->read($name);
+            $data = NestedArray::mergeDeep($existing_data, $data);
+          }
           $config->setData($data ? $data : array());
           $config->save();
         }
diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php
index 81fe970..87ddf19 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandler.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php
@@ -502,7 +502,7 @@ public static function parseDependency($dependency) {
   /**
    * {@inheritdoc}
    */
-  public function enable($module_list, $enable_dependencies = TRUE) {
+  public function enable($module_list, $enable_dependencies = TRUE, $overwrite_config = FALSE) {
     if ($enable_dependencies) {
       // Get all module data so we can find dependencies and sort.
       $module_data = system_rebuild_module_data();
@@ -643,7 +643,7 @@ public function enable($module_list, $enable_dependencies = TRUE) {
           $version = $versions ? max($versions) : SCHEMA_INSTALLED;
 
           // Install default configuration of the module.
-          config_install_default_config('module', $module);
+          config_install_default_config('module', $module, $overwrite_config);
 
           // If the module has no current updates, but has some that were
           // previously removed, set the version to the value of
diff --git a/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php b/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php
index b93e3e8..acf867f 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php
@@ -279,6 +279,14 @@ public function alter($type, &$data, &$context1 = NULL, &$context2 = NULL);
    *   If TRUE, dependencies will automatically be added and enabled in the
    *   correct order. This incurs a significant performance cost, so use FALSE
    *   if you know $module_list is already complete and in the correct order.
+   * @param $overwrite_config
+   *   If FALSE (default), the default configuration for this module will not
+   *   replace any existing configuration. Any current configuration which
+   *   overlaps with the default values provided by the module will be left
+   *   intact.
+   *   If TRUE, the default configuration for this module will be merged into
+   *   any existing configuration, allowing the module to overwrite current
+   *   configuration. This normally only applies to installation profiles.
    *
    * @return
    *   FALSE if one or more dependencies are missing, TRUE otherwise.
@@ -288,7 +296,7 @@ public function alter($type, &$data, &$context1 = NULL, &$context2 = NULL);
    * @see hook_modules_installed()
    * @see hook_modules_enabled()
    */
-  public function enable($module_list, $enable_dependencies = TRUE);
+  public function enable($module_list, $enable_dependencies = TRUE, $overwrite_config = FALSE);
 
   /**
    * Disables a given set of modules.
diff --git a/core/lib/Drupal/Core/Extension/UpdateModuleHandler.php b/core/lib/Drupal/Core/Extension/UpdateModuleHandler.php
index 78553d9..1e1ddff 100644
--- a/core/lib/Drupal/Core/Extension/UpdateModuleHandler.php
+++ b/core/lib/Drupal/Core/Extension/UpdateModuleHandler.php
@@ -58,7 +58,7 @@ public function getImplementations($hook) {
   /**
    * {@inheritdoc}
    */
-  public function enable($module_list, $enable_dependencies = TRUE) {
+  public function enable($module_list, $enable_dependencies = TRUE, $overwrite_config = FALSE) {
     $schema_store = \Drupal::keyValue('system.schema');
     $old_schema = array();
     foreach ($module_list as $module) {
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigInstallWebTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigInstallWebTest.php
index 5431a96..4b4757f 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigInstallWebTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigInstallWebTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\config\Tests;
 
 use Drupal\simpletest\WebTestBase;
+use Drupal\Core\Config\FileStorage;
 
 /**
  * Tests installation of configuration objects in installation functionality.
@@ -105,4 +106,58 @@ function testIntegrationModuleReinstallation() {
     $this->assertIdentical($config_entity->get('label'), 'Customized integration config label');
   }
 
+  /**
+   * Tests install profile config changes.
+   */
+  function testInstallProfileConfigMerge() {
+    $config_name = 'system.cron';
+    // The expected configuration from the system module.
+    $expected_original_data = array(
+      'threshold' => array(
+        'autorun' => '0',
+        'requirements_warning' => '172800',
+        'requirements_error' => '1209600',
+      ),
+    );
+    // The expected active configuration altered by the install profile.
+    $expected_overriden_data = array(
+      'threshold' => array(
+        'autorun' => '10800',
+        'requirements_warning' => '172800',
+        'requirements_error' => '1209600',
+      ),
+    );
+
+    // Enter an override-free context to ensure the original data remains.
+    config_context_enter('config.context.free');
+
+    // Verify that the original data matches. We have to read the module config
+    // file directly, otherwise install profile overrides will apply.
+    $config_dir = drupal_get_path('module', 'system') . '/config';
+    $this->assertTrue(is_dir($config_dir));
+    $source_storage = new FileStorage($config_dir);
+    $data = $source_storage->read($config_name);
+    $this->assertIdentical($data, $expected_original_data);
+
+    // Verify that active configuration matches the expected data, which has
+    // been overriden by the testing install profile.
+    $config = config($config_name);
+    $this->assertIdentical($config->get(), $expected_overriden_data);
+
+    // Turn on the test module, which will also attempt to override the
+    // configuration data, but should be prevented.
+    module_enable(array('config_override_test'));
+
+    // Verify that the test module has not been able to change the data.
+    $config = config($config_name);
+    $this->assertIdentical($config->get(), $expected_overriden_data);
+
+    // Disable and uninstall the test module.
+    module_disable(array('config_override_test'));
+    module_uninstall(array('config_override_test'));
+
+    // Verify that the data hasn't been altered by removing the test module.
+    $config = config($config_name);
+    $this->assertIdentical($config->get(), $expected_overriden_data);
+  }
 }
diff --git a/core/modules/config/tests/config_override_test/config/system.cron.yml b/core/modules/config/tests/config_override_test/config/system.cron.yml
new file mode 100644
index 0000000..036034f
--- /dev/null
+++ b/core/modules/config/tests/config_override_test/config/system.cron.yml
@@ -0,0 +1,2 @@
+threshold:
+  autorun: '0'
diff --git a/core/modules/config/tests/config_override_test/config_override_test.info.yml b/core/modules/config/tests/config_override_test/config_override_test.info.yml
new file mode 100644
index 0000000..1ccb50b
--- /dev/null
+++ b/core/modules/config/tests/config_override_test/config_override_test.info.yml
@@ -0,0 +1,6 @@
+name: 'Configuration override test'
+type: module
+package: Testing
+version: VERSION
+core: 8.x
+hidden: true
diff --git a/core/modules/config/tests/config_override_test/config_override_test.module b/core/modules/config/tests/config_override_test/config_override_test.module
new file mode 100644
index 0000000..f364ffb
--- /dev/null
+++ b/core/modules/config/tests/config_override_test/config_override_test.module
@@ -0,0 +1,6 @@
+<?php
+
+/**
+ * @file
+ * Test module containing a configuration file which matches another module.
+ */
diff --git a/core/profiles/testing/config/system.cron.yml b/core/profiles/testing/config/system.cron.yml
new file mode 100644
index 0000000..9853f6b
--- /dev/null
+++ b/core/profiles/testing/config/system.cron.yml
@@ -0,0 +1,2 @@
+threshold:
+  autorun: '10800'
