diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 67b827a..fe71f8b 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -235,6 +235,11 @@ const LANGUAGE_LOCKED = 2;
  */
 const LANGUAGE_ALL = 3;
 
+ /**
+  * The language state used when referring to the site default language.
+  */
+const LANGUAGE_DEFAULT = 4;
+
 /**
  * The type of language used to define the content language.
  */
@@ -2801,6 +2806,15 @@ function language_list($flags = LANGUAGE_CONFIGURABLE) {
   // default we remove the locked languages, but the caller may request for
   // those languages to be added as well.
   $filtered_languages = array();
+
+  // Add the site's default language if flagged as allowed value.
+  if ($flags & LANGUAGE_DEFAULT) {
+    $default = isset($default) ? $default : language_default();
+    // Rename the default language.
+    $default->name = t("Site's default language");
+    $filtered_languages['site_default'] = $default;
+  }
+
   foreach ($languages as $langcode => $language) {
     if (($language->locked && !($flags & LANGUAGE_LOCKED)) || (!$language->locked && !($flags & LANGUAGE_CONFIGURABLE))) {
       continue;
diff --git a/core/includes/language.inc b/core/includes/language.inc
index 2a0defa..7bf8811 100644
--- a/core/includes/language.inc
+++ b/core/includes/language.inc
@@ -407,11 +407,14 @@ function language_negotiation_info() {
 
     // Add the default language negotiation method.
     $negotiation_info[LANGUAGE_NEGOTIATION_DEFAULT] = array(
-      'callbacks' => array('language' => 'language_from_default'),
-      'weight' => 10,
+      'callbacks' => array(
+        'language'    => 'language_from_default',
+        'negotiation' => 'language_from_default'
+      ),
+      'weight' => 12,
       'name' => t('Default language'),
       'description' => t('Use the default site language (@language_name).', array('@language_name' => language_default()->name)),
-      'config' => 'admin/config/regional/language',
+      'config' => 'admin/config/regional/language/detection/default',
     );
 
      // Let other modules alter the list of language negotiation methods.
@@ -474,8 +477,13 @@ function language_negotiation_method_invoke($method_id, $method = NULL, $request
  * @return
  *   The default language code.
  */
-function language_from_default() {
-  return language_default()->langcode;
+function language_from_default($languages) {
+  $langcode = (string) config('language.negotiation')->get('default_langcode');
+  // Replace the site's default langcode by its real value.
+  if ($langcode == 'site_default') {
+    $langcode = language_default()->language;
+  }
+  return isset($languages[$langcode]) ? $langcode : language_default()->langcode;
 }
 
 /**
diff --git a/core/modules/language/config/language.detection.yaml b/core/modules/language/config/language.detection.yaml
new file mode 100644
index 0000000..c3ec2ee
--- /dev/null
+++ b/core/modules/language/config/language.detection.yaml
@@ -0,0 +1 @@
+default_langcode: site_default
\ No newline at end of file
diff --git a/core/modules/language/language.admin.inc b/core/modules/language/language.admin.inc
index af2b3b1..706928d 100644
--- a/core/modules/language/language.admin.inc
+++ b/core/modules/language/language.admin.inc
@@ -519,6 +519,7 @@ function language_negotiation_configure_form_table(&$form, $type) {
         '#title_display' => 'invisible',
         '#default_value' => $weight,
         '#attributes' => array('class' => array("language-method-weight-$type")),
+        '#delta' => 20,
       );
 
       $table_form['title'][$method_id] = array('#markup' => $method_name);
@@ -898,6 +899,27 @@ function language_negotiation_configure_browser_form($form, &$form_state) {
 }
 
 /**
+ * Builds the default language negotiation method configuration form.
+ */
+function language_negotiation_configure_default_form($form, &$form_state) {
+  $form['default_langcode'] = array(
+    '#type' => 'language_select',
+    '#title' => t('Language'),
+    '#languages' => LANGUAGE_CONFIGURABLE | LANGUAGE_DEFAULT,
+    '#default_value' => config('language.negotiation')->get('default_langcode'),
+  );
+
+  return system_config_form($form, $form_state);
+}
+
+/**
+ * Form submission handler for language_negotiation_configure_default_form().
+ */
+function language_negotiation_configure_default_form_submit($form, &$form_state) {
+  config('language.negotiation')->set('default_langcode', $form_state['values']['default_langcode'])->save();
+}
+
+/**
  * Theme browser configuration form as table.
  *
  * @param $variables
diff --git a/core/modules/language/language.module b/core/modules/language/language.module
index 5b62382..097cc89 100644
--- a/core/modules/language/language.module
+++ b/core/modules/language/language.module
@@ -135,6 +135,14 @@ function language_menu() {
     'access arguments' => array('administer languages'),
     'file' => 'language.admin.inc',
   );
+  $items['admin/config/regional/language/detection/default'] = array(
+    'title' => 'Default language detection configuration',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('language_negotiation_configure_default_form'),
+    'access arguments' => array('administer languages'),
+    'file' => 'language.admin.inc',
+    'type' => MENU_VISIBLE_IN_BREADCRUMB,
+  );
 
   return $items;
 }
diff --git a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
index 0b87a09..835df2d 100644
--- a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
@@ -140,6 +140,44 @@ class LanguageUILanguageNegotiationTest extends WebTestBase {
     // Configure URL language rewrite.
     variable_set('language_negotiation_url_type', LANGUAGE_TYPE_INTERFACE);
 
+    // Configure default language negotiation to use zh-hans.
+    $edit = array('default_langcode' => $langcode);
+    $this->drupalPost('admin/config/regional/language/detection/default', $edit, t('Save configuration'));
+
+    $test = array(
+      'language_negotiation' => array(LANGUAGE_NEGOTIATION_DEFAULT),
+      'path' => 'admin/config',
+      'expect' => $language_string,
+      'expected_method_id' => LANGUAGE_NEGOTIATION_DEFAULT,
+      'http_header' => $http_header_browser_fallback,
+      'message' => 'DEFAULT: UI language is switched based on default language.',
+    );
+    $this->runTest($test);
+
+    // An invalid language is selected.
+    config('language.negotiation')->set('default_langcode', NULL)->save();
+    $test = array(
+      'language_negotiation' => array(LANGUAGE_NEGOTIATION_DEFAULT),
+      'path' => 'admin/config',
+      'expect' => $default_string,
+      'expected_method_id' => LANGUAGE_NEGOTIATION_DEFAULT,
+      'http_header' => $http_header_browser_fallback,
+      'message' => "DEFAULT: UI language uses site's default language when an invalid language is configured.",
+    );
+    $this->runTest($test);
+
+    // No selected language is available.
+    config('language.negotiation')->set('default_langcode', $langcode_unknown)->save();
+    $test = array(
+      'language_negotiation' => array(LANGUAGE_NEGOTIATION_DEFAULT),
+      'path' => 'admin/config',
+      'expect' => $default_string,
+      'expected_method_id' => LANGUAGE_NEGOTIATION_DEFAULT,
+      'http_header' => $http_header_browser_fallback,
+      'message' => "DEFAULT: UI language uses site's default language when the selected language is not available.",
+    );
+    $this->runTest($test);
+
     $tests = array(
       // Default, browser preference should have no influence.
       array(
