diff --git a/core/modules/language/language.module b/core/modules/language/language.module
index 3fb39e0..957ae36 100644
--- a/core/modules/language/language.module
+++ b/core/modules/language/language.module
@@ -158,6 +158,44 @@ function language_theme() {
 }
 
 /**
+ * Implements hook_element_info().
+ */
+function language_element_info() {
+  $types['language_select'] = array(
+    '#input' => TRUE,
+    '#multiple' => FALSE,
+    '#process' => array('language_process_language_select', 'form_process_select', 'ajax_process_form'),
+    '#title' => t('Language'),
+    '#languages' => LANGUAGE_CONFIGURABLE,
+  );
+
+  return $types;
+}
+
+/**
+ * Processes a language select list form element.
+ *
+ * @param array $element
+ *   The form element to process.
+ *
+ * @return array $element
+ *   The processed form element.
+ */
+function language_process_language_select($element) {
+  // Locale has a list of predefined languages. Use that if this option is true.
+  // Don't set the options if another module(translation for example) already
+  // set the options.
+  if (!isset($element['#options'])) {
+    foreach (language_list($element['#languages']) as $langcode => $language) {
+      $element['#options'][$langcode] = $language->locked ? t('- @name -', array('@name' => $language->name)) : $language->name;
+    }
+  }
+  $element['#theme'] = 'select';
+  $element['#theme_wrappers'] = array('form_element');
+  return $element;
+}
+
+/**
  * API function to add or update a language.
  *
  * @param $language
diff --git a/core/modules/language/lib/Drupal/language/Tests/LanguageSelectElementTest.php b/core/modules/language/lib/Drupal/language/Tests/LanguageSelectElementTest.php
new file mode 100644
index 0000000..cab11a3
--- /dev/null
+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageSelectElementTest.php
@@ -0,0 +1,63 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\language\Tests\LanguageSelectElementTest.
+ */
+
+namespace Drupal\language\Tests;
+
+use Drupal\simpletest\WebTestBase;
+use Drupal\Core\Language\Language;
+
+/**
+ * Functional tests for the language select form element.
+ */
+class LanguageSelectElementTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('language', 'language_select_test');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Language select form element',
+      'description' => 'Checks that the language select form element prints the right options.',
+      'group' => 'Form API',
+    );
+  }
+
+  /**
+   * Tests that the options printed by the language select element are correct.
+   */
+  function testLanguageSelectElementOptions() {
+    // Request a page with all the languages in the element, in the same order.
+    $this->drupalGet('language_select/test-form-element');
+    // Check that the language fields were rendered on the page.
+    $ids = array('edit-languages-all' => LANGUAGE_ALL,
+                 'edit-languages-configurable' => LANGUAGE_CONFIGURABLE,
+                 'edit-languages-locked' => LANGUAGE_LOCKED,
+                 'edit-languages-config-and-locked' => LANGUAGE_CONFIGURABLE | LANGUAGE_LOCKED);
+    foreach ($ids as $id => $flags) {
+      $this->assertField($id, t('The @id field was found on the page.', array('@id' => $id)));
+      $this->_testLanguageSelectElementOptions($id, language_list($flags));
+    }
+  }
+
+  protected function _testLanguageSelectElementOptions($id, $languages) {
+    // Check that the options in the language field are exactly the same,
+    // including the order, as the languages sent as a parameter.
+    $elements = $this->xpath("//select[@id='" . $id . "']");
+    $count = 0;
+    foreach ($elements[0]->option as $option) {
+      $count++;
+      $language = current($languages);
+      $this->assertEqual((string) $option, $language->locked ? t('- @name -', array('@name' => $language->name)) : $language->name);
+      next($languages);
+    }
+    $this->assertEqual($count, count($languages), t('The number of languages and the number of options shown by the language element is different. @languages languages, @number options', array('@languages' => count($languages), '@number' => $count)));
+  }
+}
diff --git a/core/modules/language/tests/language_select_test/language_select_test.info b/core/modules/language/tests/language_select_test/language_select_test.info
new file mode 100644
index 0000000..fc3fa5c
--- /dev/null
+++ b/core/modules/language/tests/language_select_test/language_select_test.info
@@ -0,0 +1,5 @@
+name = "Language Select Test"
+description = "Support module for testing the language select element."
+core = 8.x
+package = Testing
+hidden = TRUE
diff --git a/core/modules/language/tests/language_select_test/language_select_test.module b/core/modules/language/tests/language_select_test/language_select_test.module
new file mode 100644
index 0000000..e8da1a3
--- /dev/null
+++ b/core/modules/language/tests/language_select_test/language_select_test.module
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * Mock module for the language select form element tests.
+ */
+
+/**
+ * Implements hook_menu().
+ */
+function language_select_test_menu() {
+  $items['language_select/test-form-element'] = array(
+    'title' => 'Test language select element',
+    'access callback' => TRUE,
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('language_select_test_form'),
+  );
+  return $items;
+}
+
+function language_select_test_form() {
+  $form['languages_all'] = array(
+    '#type' => 'language_select',
+    '#languages' => LANGUAGE_ALL,
+  );
+  $form['languages_configurable'] = array(
+    '#type' => 'language_select',
+    '#languages' => LANGUAGE_CONFIGURABLE,
+  );
+  $form['languages_locked'] = array(
+    '#type' => 'language_select',
+    '#languages' => LANGUAGE_LOCKED,
+  );
+  $form['languages_config_and_locked'] = array(
+    '#type' => 'language_select',
+    '#languages' => LANGUAGE_CONFIGURABLE | LANGUAGE_LOCKED,
+  );
+  return $form;
+}
