diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index e7da6ec..7b6421a 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -236,6 +236,11 @@ const LANGUAGE_LOCKED = 2;
 const LANGUAGE_ALL = 3;
 
 /**
+ * The language state used when referring to the site's default language.
+ */
+const LANGUAGE_DEFAULT = 4;
+
+/**
  * The type of language used to define the content language.
  */
 const LANGUAGE_TYPE_CONTENT = 'language_content';
@@ -2807,6 +2812,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 (@lang_name)", array('@lang_name' => $default->name));
+    $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..122670c 100644
--- a/core/includes/language.inc
+++ b/core/includes/language.inc
@@ -10,7 +10,7 @@
 /**
  * No language negotiation. The default language is used.
  */
-const LANGUAGE_NEGOTIATION_DEFAULT = 'language-default';
+const LANGUAGE_NEGOTIATION_SELECTED = 'language-selected';
 
 /**
  * @defgroup language_negotiation Language Negotiation API functionality
@@ -133,7 +133,7 @@ function language_types_initialize($type, $request = NULL) {
 
   // If no other language was found use the default one.
   $language = language_default();
-  $language->method_id = LANGUAGE_NEGOTIATION_DEFAULT;
+  $language->method_id = LANGUAGE_NEGOTIATION_SELECTED;
   return $language;
 }
 
@@ -263,7 +263,7 @@ function language_types_set() {
  */
 function language_negotiation_method_get_first($type) {
   $negotiation = variable_get("language_negotiation_$type", array());
-  return empty($negotiation) ? LANGUAGE_NEGOTIATION_DEFAULT : key($negotiation);
+  return empty($negotiation) ? LANGUAGE_NEGOTIATION_SELECTED : key($negotiation);
 }
 
 /**
@@ -404,14 +404,20 @@ function language_negotiation_info() {
   if (!isset($negotiation_info)) {
     // Collect all the module-defined language negotiation methods.
     $negotiation_info = module_invoke_all('language_negotiation_info');
-
+    $languages = language_list();
+    $selected_language = $languages[language_from_selected($languages)];
+    $description = 'Language based on a selected language. ';
+    $description .= ($selected_language->langcode == language_default()->langcode) ? "(Site's default language (@language_name))" : '(@language_name)';
     // Add the default language negotiation method.
-    $negotiation_info[LANGUAGE_NEGOTIATION_DEFAULT] = array(
-      'callbacks' => array('language' => 'language_from_default'),
-      'weight' => 10,
-      'name' => t('Default language'),
-      'description' => t('Use the default site language (@language_name).', array('@language_name' => language_default()->name)),
-      'config' => 'admin/config/regional/language',
+    $negotiation_info[LANGUAGE_NEGOTIATION_SELECTED] = array(
+      'callbacks' => array(
+        'language'    => 'language_from_default',
+        'negotiation' => 'language_from_selected',
+      ),
+      'weight' => 12,
+      'name' => t('Selected language'),
+      'description' => t($description, array('@language_name' => $selected_language->name)),
+      'config' => 'admin/config/regional/language/detection/selected',
     );
 
      // Let other modules alter the list of language negotiation methods.
@@ -478,6 +484,24 @@ function language_from_default() {
   return language_default()->langcode;
 }
 
+ /**
+  * Identifies language from configuration.
+  *
+  * @param $languages
+  *   An array of valid language objects.
+  *
+  * @return
+  *   A valid language code on success, FALSE otherwise.
+  */
+function language_from_selected($languages) {
+  $langcode = (string) config('language.negotiation')->get('selected_langcode');
+  // Replace the site's default langcode by its real value.
+  if ($langcode == 'site_default') {
+    $langcode = language_default()->langcode;
+  }
+  return isset($languages[$langcode]) ? $langcode : language_default()->langcode;
+}
+
 /**
  * Splits the given path into prefix and actual path.
  *
diff --git a/core/modules/language/config/language.detection.yml b/core/modules/language/config/language.detection.yml
new file mode 100644
index 0000000..1299603
--- /dev/null
+++ b/core/modules/language/config/language.detection.yml
@@ -0,0 +1 @@
+selected_langcode: site_default
diff --git a/core/modules/language/language.admin.inc b/core/modules/language/language.admin.inc
index af2b3b1..8affe0a 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);
@@ -529,7 +530,7 @@ function language_negotiation_configure_form_table(&$form, $type) {
         '#title_display' => 'invisible',
         '#default_value' => $enabled,
       );
-      if ($method_id === LANGUAGE_NEGOTIATION_DEFAULT) {
+      if ($method_id === LANGUAGE_NEGOTIATION_SELECTED) {
         $table_form['enabled'][$method_id]['#default_value'] = TRUE;
         $table_form['enabled'][$method_id]['#attributes'] = array('disabled' => 'disabled');
       }
@@ -624,7 +625,7 @@ function language_negotiation_configure_form_submit($form, &$form_state) {
   foreach ($configurable_types as $type) {
     $method_weights = array();
     $enabled_methods = $form_state['values'][$type]['enabled'];
-    $enabled_methods[LANGUAGE_NEGOTIATION_DEFAULT] = TRUE;
+    $enabled_methods[LANGUAGE_NEGOTIATION_SELECTED] = TRUE;
     $method_weights_input = $form_state['values'][$type]['weight'];
 
     foreach ($method_weights_input as $method_id => $weight) {
@@ -815,6 +816,27 @@ function language_negotiation_configure_session_form($form, &$form_state) {
 }
 
 /**
+ * Builds the selected language negotiation method configuration form.
+ */
+function language_negotiation_configure_selected_form($form, &$form_state) {
+  $form['selected_langcode'] = array(
+    '#type' => 'language_select',
+    '#title' => t('Language'),
+    '#languages' => LANGUAGE_CONFIGURABLE | LANGUAGE_DEFAULT,
+    '#default_value' => config('language.negotiation')->get('selected_langcode'),
+  );
+
+  return system_config_form($form, $form_state);
+}
+
+/**
+ * Form submission handler for language_negotiation_configure_selected_form().
+ */
+function language_negotiation_configure_selected_form_submit($form, &$form_state) {
+  config('language.negotiation')->set('selected_langcode', $form_state['values']['selected_langcode'])->save();
+}
+
+/**
  * Builds the browser language negotiation method configuration form.
  */
 function language_negotiation_configure_browser_form($form, &$form_state) {
diff --git a/core/modules/language/language.module b/core/modules/language/language.module
index 5b62382..b6eabbd 100644
--- a/core/modules/language/language.module
+++ b/core/modules/language/language.module
@@ -41,6 +41,10 @@ function language_help($path, $arg) {
       $output = '<p>' . t('Browsers use different language codes to refer to the same languages. You can add and edit mappings from browser language codes to the <a href="@configure-languages">languages used by Drupal</a>.', array('@configure-languages' => url('admin/config/regional/language'))) . '</p>';
       return $output;
 
+    case 'admin/config/regional/language/detection/selected':
+      $output = '<p>' . t("Determine the language from a selected language or the site's default language. Selecting a different language here is preferred over <a href='@default-lang-configuration'>changing your site's default language directly</a>.", array('@default-lang-configuration' => url('admin/config/regional/language'))) . '</p>';
+      return $output;
+
     case 'admin/structure/block/manage/%/%':
       if ($arg[4] == 'language' && $arg[5] == 'language_interface') {
         return '<p>' . t('With multiple languages enabled, registered users can select their preferred language and authors can assign a specific language to content.') . '</p>';
@@ -135,6 +139,14 @@ function language_menu() {
     'access arguments' => array('administer languages'),
     'file' => 'language.admin.inc',
   );
+  $items['admin/config/regional/language/detection/selected'] = array(
+    'title' => 'Selected language detection configuration',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('language_negotiation_configure_selected_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..6de762d 100644
--- a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
@@ -140,19 +140,56 @@ class LanguageUILanguageNegotiationTest extends WebTestBase {
     // Configure URL language rewrite.
     variable_set('language_negotiation_url_type', LANGUAGE_TYPE_INTERFACE);
 
+    // Configure selected language negotiation to use zh-hans.
+    $edit = array('selected_langcode' => $langcode);
+    $this->drupalPost('admin/config/regional/language/detection/selected', $edit, t('Save configuration'));
+    $test = array(
+      'language_negotiation' => array(LANGUAGE_NEGOTIATION_SELECTED),
+      'path' => 'admin/config',
+      'expect' => $language_string,
+      'expected_method_id' => LANGUAGE_NEGOTIATION_SELECTED,
+      'http_header' => $http_header_browser_fallback,
+      'message' => 'SELECTED: UI language is switched based on selected language.',
+    );
+    $this->runTest($test);
+
+    // An invalid language is selected.
+    config('language.negotiation')->set('selected_langcode', NULL)->save();
+    $test = array(
+      'language_negotiation' => array(LANGUAGE_NEGOTIATION_SELECTED),
+      'path' => 'admin/config',
+      'expect' => $default_string,
+      'expected_method_id' => LANGUAGE_NEGOTIATION_SELECTED,
+      'http_header' => $http_header_browser_fallback,
+      'message' => 'SELECTED > DEFAULT: UI language is switched based on selected language.',
+    );
+    $this->runTest($test);
+
+    // No selected language is available.
+    config('language.negotiation')->set('selected_langcode', $langcode_unknown)->save();
+    $test = array(
+      'language_negotiation' => array(LANGUAGE_NEGOTIATION_SELECTED),
+      'path' => 'admin/config',
+      'expect' => $default_string,
+      'expected_method_id' => LANGUAGE_NEGOTIATION_SELECTED,
+      'http_header' => $http_header_browser_fallback,
+      'message' => 'SELECTED > DEFAULT: UI language is switched based on selected language.',
+    );
+    $this->runTest($test);
+
     $tests = array(
       // Default, browser preference should have no influence.
       array(
-        'language_negotiation' => array(LANGUAGE_NEGOTIATION_URL, LANGUAGE_NEGOTIATION_DEFAULT),
+        'language_negotiation' => array(LANGUAGE_NEGOTIATION_URL, LANGUAGE_NEGOTIATION_SELECTED),
         'path' => 'admin/config',
         'expect' => $default_string,
-        'expected_method_id' => LANGUAGE_NEGOTIATION_DEFAULT,
+        'expected_method_id' => LANGUAGE_NEGOTIATION_SELECTED,
         'http_header' => $http_header_browser_fallback,
         'message' => 'URL (PATH) > DEFAULT: no language prefix, UI language is default and the browser language preference setting is not used.',
       ),
       // Language prefix.
       array(
-        'language_negotiation' => array(LANGUAGE_NEGOTIATION_URL, LANGUAGE_NEGOTIATION_DEFAULT),
+        'language_negotiation' => array(LANGUAGE_NEGOTIATION_URL, LANGUAGE_NEGOTIATION_SELECTED),
         'path' => "$langcode/admin/config",
         'expect' => $language_string,
         'expected_method_id' => LANGUAGE_NEGOTIATION_URL,
@@ -179,10 +216,10 @@ class LanguageUILanguageNegotiationTest extends WebTestBase {
       ),
       // Default, browser language preference is not one of site's lang.
       array(
-        'language_negotiation' => array(LANGUAGE_NEGOTIATION_URL, LANGUAGE_NEGOTIATION_BROWSER, LANGUAGE_NEGOTIATION_DEFAULT),
+        'language_negotiation' => array(LANGUAGE_NEGOTIATION_URL, LANGUAGE_NEGOTIATION_BROWSER, LANGUAGE_NEGOTIATION_SELECTED),
         'path' => 'admin/config',
         'expect' => $default_string,
-        'expected_method_id' => LANGUAGE_NEGOTIATION_DEFAULT,
+        'expected_method_id' => LANGUAGE_NEGOTIATION_SELECTED,
         'http_header' => $http_header_blah,
         'message' => 'URL (PATH) > BROWSER > DEFAULT: no language prefix and browser language preference set to unknown language should use default language',
       ),
@@ -204,10 +241,10 @@ class LanguageUILanguageNegotiationTest extends WebTestBase {
 
     $tests = array(
       array(
-        'language_negotiation' => array(LANGUAGE_NEGOTIATION_USER, LANGUAGE_NEGOTIATION_DEFAULT),
+        'language_negotiation' => array(LANGUAGE_NEGOTIATION_USER, LANGUAGE_NEGOTIATION_SELECTED),
         'path' => 'admin/config',
         'expect' => $default_string,
-        'expected_method_id' => LANGUAGE_NEGOTIATION_DEFAULT,
+        'expected_method_id' => LANGUAGE_NEGOTIATION_SELECTED,
         'http_header' => array(),
         'message' => 'USER > DEFAULT: no preferred user language setting, the UI language is default',
       ),
@@ -220,10 +257,10 @@ class LanguageUILanguageNegotiationTest extends WebTestBase {
 
     $tests = array(
       array(
-        'language_negotiation' => array(LANGUAGE_NEGOTIATION_USER, LANGUAGE_NEGOTIATION_DEFAULT),
+        'language_negotiation' => array(LANGUAGE_NEGOTIATION_USER, LANGUAGE_NEGOTIATION_SELECTED),
         'path' => 'admin/config',
         'expect' => $default_string,
-        'expected_method_id' => LANGUAGE_NEGOTIATION_DEFAULT,
+        'expected_method_id' => LANGUAGE_NEGOTIATION_SELECTED,
         'http_header' => array(),
         'message' => 'USER > DEFAULT: invalid preferred user language setting, the UI language is default',
       ),
@@ -236,7 +273,7 @@ class LanguageUILanguageNegotiationTest extends WebTestBase {
 
     $tests = array(
       array(
-        'language_negotiation' => array(LANGUAGE_NEGOTIATION_USER, LANGUAGE_NEGOTIATION_DEFAULT),
+        'language_negotiation' => array(LANGUAGE_NEGOTIATION_USER, LANGUAGE_NEGOTIATION_SELECTED),
         'path' => 'admin/config',
         'expect' => $language_string,
         'expected_method_id' => LANGUAGE_NEGOTIATION_USER,
@@ -255,10 +292,10 @@ class LanguageUILanguageNegotiationTest extends WebTestBase {
 
     $tests = array(
       array(
-        'language_negotiation' => array(LANGUAGE_NEGOTIATION_USER_ADMIN, LANGUAGE_NEGOTIATION_DEFAULT),
+        'language_negotiation' => array(LANGUAGE_NEGOTIATION_USER_ADMIN, LANGUAGE_NEGOTIATION_SELECTED),
         'path' => 'admin/config',
         'expect' => $default_string,
-        'expected_method_id' => LANGUAGE_NEGOTIATION_DEFAULT,
+        'expected_method_id' => LANGUAGE_NEGOTIATION_SELECTED,
         'http_header' => array(),
         'message' => 'USER ADMIN > DEFAULT: no preferred user admin language setting, the UI language is default',
       ),
@@ -270,10 +307,10 @@ class LanguageUILanguageNegotiationTest extends WebTestBase {
 
     $tests = array(
       array(
-        'language_negotiation' => array(LANGUAGE_NEGOTIATION_USER_ADMIN, LANGUAGE_NEGOTIATION_DEFAULT),
+        'language_negotiation' => array(LANGUAGE_NEGOTIATION_USER_ADMIN, LANGUAGE_NEGOTIATION_SELECTED),
         'path' => 'admin/config',
         'expect' => $default_string,
-        'expected_method_id' => LANGUAGE_NEGOTIATION_DEFAULT,
+        'expected_method_id' => LANGUAGE_NEGOTIATION_SELECTED,
         'http_header' => array(),
         'message' => 'USER ADMIN > DEFAULT: invalid preferred user admin language setting, the UI language is default',
       ),
@@ -285,7 +322,7 @@ class LanguageUILanguageNegotiationTest extends WebTestBase {
 
     $tests = array(
       array(
-        'language_negotiation' => array(LANGUAGE_NEGOTIATION_USER_ADMIN, LANGUAGE_NEGOTIATION_DEFAULT),
+        'language_negotiation' => array(LANGUAGE_NEGOTIATION_USER_ADMIN, LANGUAGE_NEGOTIATION_SELECTED),
         'path' => 'admin/config',
         'expect' => $language_string,
         'expected_method_id' => LANGUAGE_NEGOTIATION_USER_ADMIN,
@@ -307,18 +344,18 @@ class LanguageUILanguageNegotiationTest extends WebTestBase {
     $tests = array(
       // Default domain, browser preference should have no influence.
       array(
-        'language_negotiation' => array(LANGUAGE_NEGOTIATION_URL, LANGUAGE_NEGOTIATION_DEFAULT),
+        'language_negotiation' => array(LANGUAGE_NEGOTIATION_URL, LANGUAGE_NEGOTIATION_SELECTED),
         'language_negotiation_url_part' => LANGUAGE_NEGOTIATION_URL_DOMAIN,
         'path' => 'admin/config',
         'expect' => $default_string,
-        'expected_method_id' => LANGUAGE_NEGOTIATION_DEFAULT,
+        'expected_method_id' => LANGUAGE_NEGOTIATION_SELECTED,
         'http_header' => $http_header_browser_fallback,
         'message' => 'URL (DOMAIN) > DEFAULT: default domain should get default language',
       ),
       // Language domain specific URL, we set the $_SERVER['HTTP_HOST'] in
       // language_test.module hook_boot() to simulate this.
       array(
-        'language_negotiation' => array(LANGUAGE_NEGOTIATION_URL, LANGUAGE_NEGOTIATION_DEFAULT),
+        'language_negotiation' => array(LANGUAGE_NEGOTIATION_URL, LANGUAGE_NEGOTIATION_SELECTED),
         'language_negotiation_url_part' => LANGUAGE_NEGOTIATION_URL_DOMAIN,
         'language_test_domain' => $language_domain . ':88',
         'path' => 'admin/config',
