diff --git a/core/includes/config.inc b/core/includes/config.inc
index 8c2772b..2252583 100644
--- a/core/includes/config.inc
+++ b/core/includes/config.inc
@@ -1,6 +1,13 @@
 <?php
 
 use Drupal\Core\Config\DrupalVerifiedStorageSQL;
+use Drupal\Core\Config\DrupalConfigTree;
+
+/**
+ * The value a module should return from hook_config_reload() to indicate that
+ * it should be called again by the config system during this reload.
+ */
+const CONFIG_DEFER_RELOAD = 'CONFIG_DEFER_RELOAD';
 
 /**
  * @file
@@ -26,7 +33,7 @@ function config_get_config_directory() {
 }
 
 /**
- * Moves the default config supplied by a module to the live config directory.
+ * Moves the default config supplied by a module to the active store.
  *
  * @param
  *   The name of the module we are installing.
@@ -119,9 +126,9 @@ function config_get_verified_storage_names_with_prefix($prefix = '') {
  *   The name of the configuration object to retrieve. The name corresponds to
  *   an XML configuration file. For @code config(book.admin) @endcode, the
  *   config object returned will contain the contents of book.admin.xml.
- * @param $class
- *   The class name of the config object to be returned. Defaults to
- *   DrupalConfig.
+ * @param $storage_class
+ *   The class name of the storage driver for the DrupalConfig object to use.
+ *   Defaults to DrupalVerifiedStorageSQL.
  *
  * @return
  *   An instance of the class specified in the $class parameter.
@@ -129,8 +136,11 @@ function config_get_verified_storage_names_with_prefix($prefix = '') {
  * @todo Replace this with an appropriate factory / ability to inject in
  *   alternate storage engines..
  */
-function config($name, $class = 'Drupal\Core\Config\DrupalConfig') {
-  return new $class(new DrupalVerifiedStorageSQL($name));
+function config($name, $storage_class = NULL) {
+  if ($storage_class === NULL) {
+    $storage_class = variable_get('config_default_storage', 'Drupal\Core\Config\DrupalVerifiedStorageSQL');
+  }
+  return new Drupal\Core\Config\DrupalConfig(new $storage_class($name));
 }
 
 /**
@@ -202,7 +212,7 @@ function config_xml_to_array($data) {
  */
 function config_encode($data) {
   // Convert the supplied array into a SimpleXMLElement.
-  $xml_object = new SimpleXMLElement("<?xml version=\"1.0\"?><config></config>");
+  $xml_object = new SimpleXMLElement("<?xml version=\"1.0\"?" . "><config></config>");
   config_array_to_xml($data, $xml_object);
 
   // Pretty print the result.
@@ -240,3 +250,165 @@ function config_array_to_xml($array, &$xml_object) {
     }
   }
 }
+
+/**
+ * Reload config from disc and write new settings to the active store.
+ */
+function config_reload_from_disc() {
+  $lock_attempts = 0;
+  $lock_acquired = FALSE;
+  do {
+    if ($lock_acquired = lock_acquire(__FUNCTION__, 2)) {
+      // Find out what has changed, and pass the keys for new, changed and
+      // deleted config objects to modules.
+      $config_changes = config_get_changes_from_disc();
+
+      // Only proceed if there are changes.
+      if (empty($config_changes['new']) && empty($config_changes['changed']) && empty($config_changes['deleted'])) {
+        lock_release(__FUNCTION__);
+        return;
+      }
+
+      try {
+        // Let modules react before we overrwrite the active store, so that they
+        // can compare old values (active store) to new values (disc), and act
+        // accordingly.
+        $active_config_tree = config_tree();
+        $file_config_tree = config_tree('Drupal\Core\Config\DrupalConfigFile');
+        $modules = config_sort_module_reload_dependencies(module_implements('config_reload_from_disc'));
+        do {
+          // Keep a copy, so we can check that we're not in a loop.
+          $initial_module_list = $modules;
+          $modules = config_run_reload_hooks($config_changes, $active_config_tree, $file_config_tree, $modules);
+        } while ($modules && $modules != $initial_module_list);
+
+        if ($modules) {
+          // We got stuck in a loop processing this reload, bail.
+          throw new Exception("Dependency loop detected while reloading configuration from disc.");
+        }
+
+        // Bring the changes from disc into the active store.
+        foreach (array('new', 'changed', 'deleted') as $type) {
+          foreach ($config_changes[$type] as $name) {
+            if ($type == 'deleted') {
+              config($name)->delete();
+            }
+            else {
+              // Get the active store object, set the new data from file, then
+              // save, which will also update the .sig file.
+              $active_store_config = config($name);
+              $active_store_config->setData(config($name, 'Drupal\Core\Config\DrupalConfigFile')->get());
+              $active_store_config->save();
+            }
+          }
+        }
+        lock_release(__FUNCTION__);
+      }
+      catch (Exception $e) {
+        lock_release(__FUNCTION__);
+        throw new Exception("An error occurred reloading from disc: " . $e->getMessage());
+      }
+    }
+    else {
+      lock_wait(__FUNCTION__, 2);
+    }
+  } while ($lock_acquired === FALSE && ++$lock_attempts < 5);
+  // Oh noes, we failed after 5 attempts, watchdog()? Throw an exception?
+}
+
+/**
+ * Runs hook_config_reload implementations.
+ *
+ * @param $config_changes
+ *   An array of changes to be loaded.
+ * @param $active_config_tree
+ *   A ConfigTree object pointing at the active store.
+ * @param $file_config_tree
+ *   A ConfigTree object pointing at the disc.
+ * @return
+ *   A list of modules to run again for this reload.
+ */
+function config_run_reload_hooks($config_changes, $active_config_tree, $file_config_tree, $modules) {
+  $modules_to_rerun = array();
+  foreach ($modules as $module) {
+    $function = $module . '_config_reload_from_disc';
+    if ($function($config_changes, $file_config_tree, $active_config_tree) === CONFIG_DEFER_RELOAD) {
+      $modules_to_rerun[] = $module;
+    }
+  }
+  return $modules_to_rerun;
+}
+
+/**
+ * Load all the config names! From disc.
+ */
+function config_get_names_from_disc() {
+  $config_names = array();
+  foreach (glob(config_get_config_directory() . '/' . '*.xml') as $key => $file) {
+    $parts = explode('/', $file);
+    $file = array_pop($parts);
+    $name = str_replace('.xml', '', $file);
+    $config_names[] = $name;
+  }
+  return $config_names;
+}
+
+/**
+ * Returns a DrupalConfigTree object with the given storage backend.
+ *
+ * @param $storage_class
+ *   A storage class.
+ * @return
+ *   A DrupalConfigTree object.
+ */
+function config_tree($storage_class = NULL) {
+  if ($storage_class === NULL) {
+    $storage_class = variable_get('config_default_storage', 'Drupal\Core\Config\DrupalVerifiedStorageSQL');
+  }
+  return new DrupalConfigTree($storage_class);
+}
+
+/**
+ * Sort the given list of modules based on dependency.
+ *
+ * @param $modules
+ *   A list of modules.
+ * @return
+ *   The list of modules sorted by dependency.
+ */
+function config_sort_module_reload_dependencies($modules) {
+  // Get all module data so we can find find weights and sort.
+  $module_data = system_rebuild_module_data();
+
+  $sorted_modules = array();
+  foreach ($modules as $module) {
+    $sorted_modules[$module] = $module_data[$module]->sort;
+  }
+  arsort($sorted_modules);
+  return array_keys($sorted_modules);
+}
+
+/**
+ * Returns a list of changes on disc compared to the active store.
+ *
+ * @return
+ *   The list of files changed on disc compared to the active store.
+ */
+function config_get_changes_from_disc() {
+  $disc_config_names = config_get_names_from_disc();
+  $active_config_names = config_get_verified_storage_names_with_prefix();
+  $config_changes = array(
+    'new' => array_diff($disc_config_names, $active_config_names),
+    'changed' => array(),
+    'deleted' => array_diff($active_config_names, $disc_config_names),
+  );
+  foreach (array_intersect($disc_config_names, $active_config_names) as $name) {
+    $active_config = config($name);
+    $file_config = config($name, 'Drupal\Core\Config\DrupalConfigFile');
+    if ($active_config->get() != $file_config->get()) {
+      $config_changes['changed'][] = $name;
+    }
+  }
+  return $config_changes;
+}
+
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 493246c..8bdd116 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -1034,7 +1034,7 @@ function install_settings_form_submit($form, &$form_state) {
   $config_path = conf_path() . '/files/' . $settings['config_directory_name']['value'];
   if (!file_prepare_directory($config_path, FILE_CREATE_DIRECTORY)) {
     // How best to handle errors here?
-  };
+  }
 
   // Write out a .htaccess file that will protect the config directory from
   // prying eyes.
diff --git a/core/includes/module.inc b/core/includes/module.inc
index aa9eaf5..7cdc2d3 100644
--- a/core/includes/module.inc
+++ b/core/includes/module.inc
@@ -461,7 +461,7 @@ function module_enable($module_list, $enable_dependencies = TRUE) {
         $versions = drupal_get_schema_versions($module);
         $version = $versions ? max($versions) : SCHEMA_INSTALLED;
 
-        // Copy any default configuration data to the system config directory/
+        // Copy any default configuration data to the active store.
         config_install_default_config($module);
 
         // If the module has no current updates, but has some that were
diff --git a/core/lib/Drupal/Core/Config/DrupalConfig.php b/core/lib/Drupal/Core/Config/DrupalConfig.php
index 54397e7..6207daa 100644
--- a/core/lib/Drupal/Core/Config/DrupalConfig.php
+++ b/core/lib/Drupal/Core/Config/DrupalConfig.php
@@ -97,6 +97,10 @@ class DrupalConfig {
     }
   }
 
+  public function setData(array $data) {
+    $this->data = $data;
+  }
+
   /**
    * Sets value in this config object.
    *
diff --git a/core/lib/Drupal/Core/Config/DrupalConfigFile.php b/core/lib/Drupal/Core/Config/DrupalConfigFile.php
new file mode 100644
index 0000000..763ee7d
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/DrupalConfigFile.php
@@ -0,0 +1,144 @@
+<?php
+
+namespace Drupal\Core\Config;
+
+use Drupal\Core\Config\DrupalConfigVerifiedStorageInterface;
+
+/**
+ * Represents a config file.
+ */
+class DrupalConfigFile implements DrupalConfigVerifiedStorageInterface {
+
+  /**
+   * Constructs a DrupalConfigFile object.
+   *
+   * @param string $name
+   *   The name for the configuration data. Should be lowercase.
+   */
+  public function __construct($name) {
+    $this->name = $name;
+  }
+
+  /**
+   * Checks whether the XML configuration file already exists on disk.
+   *
+   * @return
+   *   Boolean based on file's existence.
+   */
+  protected function exists() {
+    return file_exists($this->getFilePath());
+  }
+
+  /**
+   * Returns the path to the XML configuration file.
+   *
+   * @return
+   *   @todo
+   */
+  public function getFilePath() {
+    return config_get_config_directory() . '/' . $this->name  . '.xml';
+  }
+
+  /**
+   * Writes the contents of the configuration file to disk.
+   *
+   * @param $data
+   *   The data to be written to the file.
+   *
+   * @throws
+   *   Exception
+   */
+  public function write($data) {
+    if (!file_put_contents($this->getFilePath(), $data)) {
+      throw new \Exception('Failed to write configuration file: ' . $this->getFilePath());
+    }
+  }
+
+  /**
+   * Returns the contents of the configuration file.
+   *
+   * @return
+   *   @todo
+   */
+  public function read() {
+    if ($this->exists()) {
+      return file_get_contents($this->getFilePath());
+    }
+    throw new \Exception('Failed to read configuration file: ' . $this->getFilePath());
+  }
+
+  /**
+   * Deletes a configuration file.
+   */
+  public function delete() {
+    return @drupal_unlink($this->getFilePath());
+  }
+
+  /**
+   * Copies the configuration data from the verified storage into a file.
+   */
+  public function copyToFile() {
+    // TODO: no-op to keep the interface happy.
+  }
+
+  /**
+   * Copies the configuration data from the file into the verified storage.
+   */
+  public function copyFromFile() {
+    // TODO: no-op to keep the interface happy.
+  }
+
+  /**
+   * Deletes the configuration data file.
+   */
+  public function deleteFile() {
+    return $this->delete();
+  }
+
+  /**
+   * Checks whether the file and the verified storage is in sync.
+   *
+   * @return
+   *   TRUE if the file and the verified storage contains the same data, FALSE
+   *   if not.
+   */
+  public function isOutOfSync() {
+    return FALSE;
+  }
+
+  /**
+   * Writes the configuration data into the active storage but not the file.
+   *
+   * @param $data
+   *   The configuration data to write into active storage.
+   */
+  public function writeToActive($data) {
+    // TODO: no-op to keep the interface happy.
+  }
+
+  /**
+   * Writes the configuration data into the file.
+   *
+   * @param $data
+   *   The configuration data to write into the file.
+   */
+  public function writeToFile($data) {
+    return $this->write($data);
+  }
+
+  /**
+   * Gets names starting with this prefix.
+   *
+   * @param $prefix
+   *   The prefix of the files we are searching for.
+   *
+   * @return
+   *   An array of file names under a branch.
+   *
+   * @see config_get_signed_file_storage_names_with_prefix()
+   */
+  public static function getNamesWithPrefix($prefix) {
+    return config_get_signed_file_storage_names_with_prefix($prefix);
+  }
+}
+
diff --git a/core/lib/Drupal/Core/Config/DrupalConfigTree.php b/core/lib/Drupal/Core/Config/DrupalConfigTree.php
new file mode 100644
index 0000000..0d551ac
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/DrupalConfigTree.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Drupal\Core\Config;
+
+class DrupalConfigTree {
+
+  protected $storage_class;
+
+  public function __construct($storage_class) {
+    $this->storage_class = $storage_class;
+  }
+
+  public function get($name) {
+    return config($name, $this->storage_class);
+  }
+
+}
+
diff --git a/core/modules/image/image.module b/core/modules/image/image.module
index bcccbf7..6005b86 100644
--- a/core/modules/image/image.module
+++ b/core/modules/image/image.module
@@ -527,6 +527,36 @@ function image_style_save($style) {
 }
 
 /**
+ * Implements hook_config_reload_from_disc().
+ */
+function image_config_reload_from_disc($config_changes, $files_config_tree, $active_config_tree) {
+  foreach ($config_changes['new'] as $file_name) {
+    if (strpos($file_name, 'image.styles.') === 0) {
+      $style = $files_config_tree->get($file_name)->get();
+      $style['is_new'] = TRUE;
+      module_invoke_all('image_style_save', $style);
+      image_style_flush($style);
+    }
+  }
+  foreach ($config_changes['changed'] as $file_name) {
+    if (strpos($file_name, 'image.styles.') === 0) {
+      $style = $files_config_tree->get($file_name)->get();
+      $style['is_new'] = FALSE;
+      module_invoke_all('image_style_save', $style);
+      image_style_flush($style);
+    }
+  }
+  foreach ($config_changes['deleted'] as $file_name) {
+    if (strpos($file_name, 'image.styles.') === 0) {
+      image_style_flush($style);
+      $style['old_name'] = $style['name'];
+      $style['name'] = '';
+      module_invoke_all('image_style_delete', $style);
+    }
+  }
+}
+
+/**
  * Delete an image style.
  *
  * @param $style
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index a45a0e3..c096b67 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -3202,3 +3202,37 @@ function system_actions_remove_orphans() {
   actions_synchronize(TRUE);
   drupal_goto('admin/config/system/actions/manage');
 }
+
+/**
+ * Reload config from disc form.
+ */
+function system_admin_config_reload_form($form, &$form_state) {
+  $config_changes = config_get_changes_from_disc();
+  if ($config_changes['new'] || $config_changes['changed'] || $config_changes['deleted']) {
+    return array(
+      'changed_files' => array(
+        '#markup' => '<pre>' . print_r($config_changes, TRUE) . '</pre>',
+      ),
+      'reload' => array(
+        '#type' => 'submit',
+        '#value' => 'Reload config from disc',
+      ),
+    );
+  }
+  else {
+    return array(
+      'no_changes' => array(
+        '#markup' => 'There are no changes on disc to reload.'
+      ),
+    );
+  }
+}
+
+/**
+ * Reload config from disc form submit handler.
+ */
+function system_admin_config_reload_form_submit($form, &$form_state) {
+  config_reload_from_disc();
+  drupal_set_message('Configuration successfully reloaded from disc.');
+}
+
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 469f996..fd2e00c 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -745,6 +745,18 @@ function system_menu() {
     'file' => 'system.admin.inc',
   );
 
+  // Config system reload.
+  $items['admin/config/config/reload'] = array(
+    'title' => 'Configuration reload',
+    'description' => 'Reload configuration from disc.',
+    'position' => 'left',
+    'weight' => -10,
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('system_admin_config_reload_form'),
+    'access arguments' => array('reload configuration from disc'),
+    'file' => 'system.admin.inc',
+  );
+
   // Media settings.
   $items['admin/config/media'] = array(
     'title' => 'Media',
