diff --git a/core/lib/Drupal/Core/Entity/ContentEntityForm.php b/core/lib/Drupal/Core/Entity/ContentEntityForm.php
index 9f96efa..d965ebb 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityForm.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityForm.php
@@ -143,8 +143,13 @@ public function setFormDisplay(EntityFormDisplayInterface $form_display, FormSta
    */
   protected function updateFormLangcode(FormStateInterface $form_state) {
     // Update the form language as it might have changed.
+    // @todo This should use an entity key for the entity language.
     if ($form_state->hasValue('langcode') && $this->isDefaultFormLangcode($form_state)) {
-      $form_state->set('langcode', $form_state->getValue('langcode'));
+      $langcode = $form_state->getValue('langcode');
+      if (is_array($langcode)) {
+        $langcode = isset($langcode[0]['value']) ? $langcode[0]['value'] : NULL;
+      }
+      $form_state->set('langcode', $langcode);
     }
   }
 
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php
index 961eb67..d524f33 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php
@@ -20,6 +20,7 @@
  *   id = "language",
  *   label = @Translation("Language"),
  *   description = @Translation("An entity field referencing a language."),
+ *   default_widget = "language_select",
  *   no_ui = TRUE,
  *   constraints = {
  *     "ComplexData" = {
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/LanguageSelectWidget.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/LanguageSelectWidget.php
new file mode 100644
index 0000000..567276c
--- /dev/null
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/LanguageSelectWidget.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Field\Plugin\Field\FieldWidget\LanguageSelectWidget.
+ */
+
+namespace Drupal\Core\Field\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Language\LanguageInterface;
+
+/**
+ * Plugin implementation of the 'Language' widget.
+ *
+ * @FieldWidget(
+ *   id = "language_select",
+ *   label = @Translation("Language select"),
+ *   field_types = {
+ *     "language"
+ *   }
+ * )
+ */
+class LanguageSelectWidget extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
+    $element['value'] = $element + array(
+      '#type' => 'language_select',
+      '#default_value' => $items[$delta]->value,
+      '#languages' => LanguageInterface::STATE_ALL,
+    );
+
+    return $element;
+  }
+
+}
diff --git a/core/modules/aggregator/src/Entity/Feed.php b/core/modules/aggregator/src/Entity/Feed.php
index 6532f36..ceb0090 100644
--- a/core/modules/aggregator/src/Entity/Feed.php
+++ b/core/modules/aggregator/src/Entity/Feed.php
@@ -153,7 +153,11 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
 
     $fields['langcode'] = BaseFieldDefinition::create('language')
       ->setLabel(t('Language code'))
-      ->setDescription(t('The feed language code.'));
+      ->setDescription(t('The feed language code.'))
+      ->setDisplayOptions('form', array(
+        'type' => 'language_select',
+        'weight' => 2,
+      ));
 
     $fields['url'] = BaseFieldDefinition::create('uri')
       ->setLabel(t('URL'))
diff --git a/core/modules/aggregator/src/FeedForm.php b/core/modules/aggregator/src/FeedForm.php
index 251bb44..f05918d 100644
--- a/core/modules/aggregator/src/FeedForm.php
+++ b/core/modules/aggregator/src/FeedForm.php
@@ -23,26 +23,6 @@ class FeedForm extends ContentEntityForm {
   /**
    * {@inheritdoc}
    */
-  public function form(array $form, FormStateInterface $form_state) {
-    $feed = $this->entity;
-
-    // @todo: convert to a language selection widget defined in the base field.
-    //   Blocked on https://drupal.org/node/2226493 which adds a generic
-    //   language widget.
-    $form['langcode'] = array(
-      '#title' => $this->t('Language'),
-      '#type' => 'language_select',
-      '#default_value' => $feed->language()->getId(),
-      '#languages' => LanguageInterface::STATE_ALL,
-      '#weight' => -4,
-    );
-
-    return parent::form($form, $form_state, $feed);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function validate(array $form, FormStateInterface $form_state) {
     $feed = $this->buildEntity($form, $form_state);
     // Check for duplicate titles.
diff --git a/core/modules/block_content/src/BlockContentForm.php b/core/modules/block_content/src/BlockContentForm.php
index 769a7f3..e1070bb 100644
--- a/core/modules/block_content/src/BlockContentForm.php
+++ b/core/modules/block_content/src/BlockContentForm.php
@@ -103,24 +103,6 @@ public function form(array $form, FormStateInterface $form_state) {
     // names.
     $form['#attributes']['class'][0] = drupal_html_class('block-' . $block->bundle() . '-form');
 
-    if ($this->moduleHandler->moduleExists('language')) {
-      $language_configuration = language_get_default_configuration('block_content', $block->bundle());
-
-      // Set the correct default language.
-      if ($block->isNew()) {
-        $language_default = $this->languageManager->getCurrentLanguage($language_configuration['langcode']);
-        $block->langcode->value = $language_default->getId();
-      }
-    }
-
-    $form['langcode'] = array(
-      '#title' => $this->t('Language'),
-      '#type' => 'language_select',
-      '#default_value' => $block->getUntranslated()->language()->getId(),
-      '#languages' => LanguageInterface::STATE_ALL,
-      '#access' => isset($language_configuration['language_show']) && $language_configuration['language_show'],
-    );
-
     $form['advanced'] = array(
       '#type' => 'vertical_tabs',
       '#weight' => 99,
diff --git a/core/modules/block_content/src/Entity/BlockContent.php b/core/modules/block_content/src/Entity/BlockContent.php
index e2320bd..f78d09d 100644
--- a/core/modules/block_content/src/Entity/BlockContent.php
+++ b/core/modules/block_content/src/Entity/BlockContent.php
@@ -156,9 +156,13 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setSetting('unsigned', TRUE);
 
     $fields['langcode'] = BaseFieldDefinition::create('language')
-      ->setLabel(t('Language code'))
+      ->setLabel(t('Language'))
       ->setDescription(t('The custom block language code.'))
-      ->setRevisionable(TRUE);
+      ->setRevisionable(TRUE)
+      ->setDisplayOptions('form', array(
+        'type' => 'language_select',
+        'weight' => 2,
+      ));
 
     $fields['info'] = BaseFieldDefinition::create('string')
       ->setLabel(t('Block description'))
diff --git a/core/modules/comment/src/CommentForm.php b/core/modules/comment/src/CommentForm.php
index 35e033d..83bbddd 100644
--- a/core/modules/comment/src/CommentForm.php
+++ b/core/modules/comment/src/CommentForm.php
@@ -161,15 +161,6 @@ public function form(array $form, FormStateInterface $form_state) {
       $form['author']['name']['#attributes']['data-drupal-default-value'] = $this->config('user.settings')->get('anonymous');
     }
 
-    $language_configuration = \Drupal::moduleHandler()->invoke('language', 'get_default_configuration', array('comment', $comment->getTypeId()));
-    $form['langcode'] = array(
-      '#title' => t('Language'),
-      '#type' => 'language_select',
-      '#default_value' => $comment->getUntranslated()->language()->getId(),
-      '#languages' => Language::STATE_ALL,
-      '#access' => isset($language_configuration['language_show']) && $language_configuration['language_show'],
-    );
-
     // Add author email and homepage fields depending on the current user.
     $form['author']['mail'] = array(
       '#type' => 'email',
diff --git a/core/modules/comment/src/Entity/Comment.php b/core/modules/comment/src/Entity/Comment.php
index 57c7287..827cc60 100644
--- a/core/modules/comment/src/Entity/Comment.php
+++ b/core/modules/comment/src/Entity/Comment.php
@@ -221,8 +221,12 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setRequired(TRUE);
 
     $fields['langcode'] = BaseFieldDefinition::create('language')
-      ->setLabel(t('Language code'))
-      ->setDescription(t('The comment language code.'));
+      ->setLabel(t('Language'))
+      ->setDescription(t('The comment language code.'))
+      ->setDisplayOptions('form', array(
+        'type' => 'language_select',
+        'weight' => 2,
+      ));
 
     $fields['subject'] = BaseFieldDefinition::create('string')
       ->setLabel(t('Subject'))
diff --git a/core/modules/comment/src/Tests/CommentLanguageTest.php b/core/modules/comment/src/Tests/CommentLanguageTest.php
index 746aea4..1d5d89d 100644
--- a/core/modules/comment/src/Tests/CommentLanguageTest.php
+++ b/core/modules/comment/src/Tests/CommentLanguageTest.php
@@ -93,7 +93,7 @@ function testCommentLanguage() {
       $edit = array(
         'title[0][value]' => $title,
         'body[0][value]' => $this->randomMachineName(),
-        'langcode' => $node_langcode,
+        'langcode[0][value]' => $node_langcode,
         'comment[0][status]' => CommentItemInterface::OPEN,
       );
       $this->drupalPostForm("node/add/article", $edit, t('Save'));
diff --git a/core/modules/contact/src/Entity/Message.php b/core/modules/contact/src/Entity/Message.php
index 20be2e8..0724312 100644
--- a/core/modules/contact/src/Entity/Message.php
+++ b/core/modules/contact/src/Entity/Message.php
@@ -144,8 +144,12 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setReadOnly(TRUE);
 
     $fields['langcode'] = BaseFieldDefinition::create('language')
-      ->setLabel(t('Language code'))
-      ->setDescription(t('The comment language code.'));
+      ->setLabel(t('Language'))
+      ->setDescription(t('The comment language code.'))
+      ->setDisplayOptions('form', array(
+        'type' => 'language_select',
+        'weight' => 2,
+      ));
 
     $fields['name'] = BaseFieldDefinition::create('string')
       ->setLabel(t("The sender's name"))
diff --git a/core/modules/contact/src/MessageForm.php b/core/modules/contact/src/MessageForm.php
index 0e280cb..ba6d469 100644
--- a/core/modules/contact/src/MessageForm.php
+++ b/core/modules/contact/src/MessageForm.php
@@ -98,15 +98,6 @@ public function form(array $form, FormStateInterface $form_state) {
       $form['preview']['message'] = $this->entityManager->getViewBuilder('contact_message')->view($message, 'full');
     }
 
-    $language_configuration = $this->moduleHandler->invoke('language', 'get_default_configuration', array('contact_message', $message->getContactForm()->id()));
-    $form['langcode'] = array(
-      '#title' => $this->t('Language'),
-      '#type' => 'language_select',
-      '#default_value' => $message->getUntranslated()->language()->getId(),
-      '#languages' => Language::STATE_ALL,
-      '#access' => isset($language_configuration['language_show']) && $language_configuration['language_show'],
-    );
-
     $form['name'] = array(
       '#type' => 'textfield',
       '#title' => $this->t('Your name'),
diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module
index ffa5d89..aac9713 100644
--- a/core/modules/content_translation/content_translation.module
+++ b/core/modules/content_translation/content_translation.module
@@ -382,9 +382,10 @@ function content_translation_form_alter(array &$form, FormStateInterface $form_s
     // Handle fields shared between translations when there is at least one
     // translation available or a new one is being created.
     if (!$entity->isNew() && (!isset($translations[$form_langcode]) || count($translations) > 1)) {
-      foreach ($entity->getFieldDefinitions() as $property_name => $definition) {
-        if (isset($form[$property_name])) {
-          $form[$property_name]['#multilingual'] = $definition->isTranslatable();
+      $langcode_key = $entity->getEntityType()->getKey('langcode') ?: 'langcode';
+      foreach ($entity->getFieldDefinitions() as $field_name => $definition) {
+        if (isset($form[$field_name]) && $field_name != $langcode_key) {
+          $form[$field_name]['#multilingual'] = $definition->isTranslatable();
         }
       }
     }
diff --git a/core/modules/content_translation/src/ContentTranslationHandler.php b/core/modules/content_translation/src/ContentTranslationHandler.php
index b1b6e9b..bcc2b19 100644
--- a/core/modules/content_translation/src/ContentTranslationHandler.php
+++ b/core/modules/content_translation/src/ContentTranslationHandler.php
@@ -12,6 +12,7 @@
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Language\LanguageInterface;
+use Drupal\Core\Language\LanguageManager;
 use Drupal\Core\Render\Element;
 
 /**
@@ -144,22 +145,33 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En
       }
     }
 
-    // Disable languages for existing translations, so it is not possible to
-    // switch this node to some language which is already in the translation
-    // set.
-    $language_widget = isset($form['langcode']) && $form['langcode']['#type'] == 'language_select';
-    if ($language_widget && $has_translations) {
-      $form['langcode']['#options'] = array();
-      foreach (language_list(LanguageInterface::STATE_CONFIGURABLE) as $language) {
-        if (empty($translations[$language->getId()]) || $language->getId() == $entity_langcode) {
-          $form['langcode']['#options'][$language->getId()] = $language->getName();
+    // Locate the language widget.
+    $language_field = $this->entityType->getKey('langcode') ?: 'langcode';
+    if (isset($form[$language_field])) {
+      $language_widget = &$form[$language_field];
+    }
+
+    // If we are editing the source entity, force the list of languages so that
+    // it is not possible to switch to a language for which a translation
+    // already exists. Note that this will only work if the widget is structured
+    // like \Drupal\Core\Field\Plugin\Field\FieldWidget\LanguageSelectWidget.
+    if (isset($language_widget['widget'][0]['value']) && !$is_translation && $has_translations) {
+      $language_select = &$language_widget['widget'][0]['value'];
+      if ($language_select['#type'] == 'language_select') {
+        $options = array();
+        foreach (\Drupal::languageManager()->getLanguages() as $language) {
+          // Show the current language, and the languages for which no
+          // translation already exists.
+          if (empty($translations[$language->getId()]) || $language->getId() == $entity_langcode) {
+            $options[$language->getId()] = $language->getName();
+          }
         }
+        $language_select['#options'] = $options;
       }
     }
-
     if ($is_translation) {
-      if ($language_widget) {
-        $form['langcode']['#access'] = FALSE;
+      if (isset($language_widget)) {
+        $language_widget['#access'] = FALSE;
       }
 
       // Replace the delete button with the delete translation one.
@@ -271,8 +283,8 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En
         '#default_value' => $new_translation ? '' : format_date($date, 'custom', 'Y-m-d H:i:s O'),
       );
 
-      if ($language_widget) {
-        $form['langcode']['#multilingual'] = TRUE;
+      if (isset($language_widget)) {
+        $language_widget['#multilingual'] = TRUE;
       }
 
       $form['#process'][] = array($this, 'entityFormSharedElements');
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationUITest.php b/core/modules/content_translation/src/Tests/ContentTranslationUITest.php
index 5e8497b..0aa6e4a 100644
--- a/core/modules/content_translation/src/Tests/ContentTranslationUITest.php
+++ b/core/modules/content_translation/src/Tests/ContentTranslationUITest.php
@@ -138,19 +138,19 @@ protected function doTestOutdatedStatus() {
     $entity = entity_load($this->entityTypeId, $this->entityId, TRUE);
     $langcode = 'fr';
     $default_langcode = $this->langcodes[0];
+    $languages = \Drupal::languageManager()->getLanguages();
 
     // Mark translations as outdated.
     $edit = array('content_translation[retranslate]' => TRUE);
-    $edit_path = $entity->getSystemPath('edit-form');
-    $this->drupalPostForm($langcode . '/' . $edit_path, $edit, $this->getFormSubmitAction($entity, $langcode));
+    $path = $entity->getSystemPath('edit-form');
+    $this->drupalPostForm($path, $edit, $this->getFormSubmitAction($entity, $langcode), array('language' => $languages[$langcode]));
     $entity = entity_load($this->entityTypeId, $this->entityId, TRUE);
 
     // Check that every translation has the correct "outdated" status, and that
     // the Translation fieldset is open if the translation is "outdated".
     foreach ($this->langcodes as $added_langcode) {
-      $prefix = $added_langcode != $default_langcode ? $added_langcode . '/' : '';
-      $path = $prefix . $edit_path;
-      $this->drupalGet($path);
+      $options = array('language' => $languages[$added_langcode]);
+      $this->drupalGet($path, $options);
       if ($added_langcode == $langcode) {
         $this->assertFieldByXPath('//input[@name="content_translation[retranslate]"]', FALSE, 'The retranslate flag is not checked by default.');
         $this->assertFalse($this->xpath('//details[@id="edit-content-translation" and @open="open"]'), 'The translation tab should be collapsed by default.');
@@ -159,8 +159,8 @@ protected function doTestOutdatedStatus() {
         $this->assertFieldByXPath('//input[@name="content_translation[outdated]"]', TRUE, 'The translate flag is checked by default.');
         $this->assertTrue($this->xpath('//details[@id="edit-content-translation" and @open="open"]'), 'The translation tab is correctly expanded when the translation is outdated.');
         $edit = array('content_translation[outdated]' => FALSE);
-        $this->drupalPostForm($path, $edit, $this->getFormSubmitAction($entity, $added_langcode));
-        $this->drupalGet($path);
+        $this->drupalPostForm($path, $edit, $this->getFormSubmitAction($entity, $added_langcode), $options);
+        $this->drupalGet($path, $options);
         $this->assertFieldByXPath('//input[@name="content_translation[retranslate]"]', FALSE, 'The retranslate flag is now shown.');
         $entity = entity_load($this->entityTypeId, $this->entityId, TRUE);
         $this->assertFalse($entity->translation[$added_langcode]['outdated'], 'The "outdated" status has been correctly stored.');
diff --git a/core/modules/language/language.module b/core/modules/language/language.module
index 6901c91..f4458d4 100644
--- a/core/modules/language/language.module
+++ b/core/modules/language/language.module
@@ -5,6 +5,8 @@
  * Add language handling functionality to Drupal.
  */
 
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Field\BaseFieldDefinition;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
@@ -13,6 +15,10 @@
 use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl;
 use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrlFallback;
 use Drupal\node\NodeTypeInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Access\AccessResult;
 
 /**
  * Implements hook_help().
@@ -171,6 +177,18 @@ function language_process_language_select($element) {
 }
 
 /**
+ * Implements hook_entity_base_field_info_alter().
+ */
+function language_entity_base_field_info_alter(&$fields) {
+  foreach ($fields as $definition) {
+    // Set configurable form display for language fields with display options.
+    if ($definition->getType() == 'language' && $definition->getDisplayOptions('form')) {
+      $definition->setDisplayConfigurable('form', TRUE);
+    }
+  }
+}
+
+/**
  * Submit handler for the forms that have a language_configuration element.
  */
 function language_configuration_element_submit(&$form, FormStateInterface $form_state) {
@@ -520,3 +538,15 @@ function language_field_info_alter(&$info) {
   // Change the default behavior of language field.
   $info['language']['class'] = '\Drupal\language\DefaultLanguageItem';
 }
+
+/**
+ * Implements hook_entity_field_access()
+ */
+function language_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
+  if ($field_definition->getName() == 'langcode') {
+    $language_configuration = language_get_default_configuration($field_definition->getTargetEntityTypeId(), $items->getEntity()->bundle());
+    return AccessResult::forbiddenIf(!$language_configuration['language_show']);
+  }
+  return AccessResult::neutral();
+}
+
diff --git a/core/modules/locale/src/Tests/LocaleContentTest.php b/core/modules/locale/src/Tests/LocaleContentTest.php
index 1bef062..f9f43f0 100644
--- a/core/modules/locale/src/Tests/LocaleContentTest.php
+++ b/core/modules/locale/src/Tests/LocaleContentTest.php
@@ -95,12 +95,12 @@ public function testContentTypeLanguageConfiguration() {
     $this->drupalLogin($web_user);
     $this->drupalGet("node/add/{$type1->type}");
     // Verify language select list is not present.
-    $this->assertNoFieldByName('language', NULL, 'Language select not present on the node add form.');
+    $this->assertNoFieldByName('langcode[0][value]', NULL, 'Language select not present on the node add form.');
 
     // Verify language selection appears on the node add form.
     $this->drupalGet("node/add/{$type2->type}");
     // Verify language select list is present.
-    $this->assertFieldByName('langcode', NULL, 'Language select present on the node add form.');
+    $this->assertFieldByName('langcode[0][value]', NULL, 'Language select present on the node add form.');
     // Ensure language appears.
     $this->assertText($name, 'Language present.');
 
@@ -120,7 +120,7 @@ public function testContentTypeLanguageConfiguration() {
     $this->assertRaw('<option value="' . $langcode . '" selected="selected">' .  $name . '</option>', 'Correct language selected.');
     // Ensure we can change the node language.
     $edit = array(
-      'langcode' => 'en',
+      'langcode[0][value]' => 'en',
     );
     $this->drupalPostForm($path, $edit, t('Save'));
     $this->assertRaw(t('%title has been updated.', array('%title' => $node_title)));
diff --git a/core/modules/menu_link_content/src/Entity/MenuLinkContent.php b/core/modules/menu_link_content/src/Entity/MenuLinkContent.php
index 9b44af0..5f4833a 100644
--- a/core/modules/menu_link_content/src/Entity/MenuLinkContent.php
+++ b/core/modules/menu_link_content/src/Entity/MenuLinkContent.php
@@ -392,8 +392,12 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ));
 
     $fields['langcode'] = BaseFieldDefinition::create('language')
-      ->setLabel(t('Language code'))
-      ->setDescription(t('The node language code.'));
+      ->setLabel(t('Language'))
+      ->setDescription(t('The node language code.'))
+      ->setDisplayOptions('form', array(
+        'type' => 'language_select',
+        'weight' => 2,
+      ));
 
     $fields['parent'] = BaseFieldDefinition::create('string')
       ->setLabel(t('Parent plugin ID'))
diff --git a/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php b/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php
index 4fb93b2..ac3d98f 100644
--- a/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php
+++ b/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php
@@ -257,21 +257,6 @@ public function form(array $form, FormStateInterface $form_state) {
       '#weight' => -2,
     );
 
-    $language_configuration = $this->moduleHandler->invoke('language', 'get_default_configuration', array('menu_link_content', 'menu_link_content'));
-    if ($this->entity->isNew()) {
-      $default_language = isset($language_configuration['langcode']) ? $language_configuration['langcode'] : $this->languageManager->getDefaultLanguage()->getId();
-    }
-    else {
-      $default_language = $this->entity->getUntranslated()->language()->getId();
-    }
-    $form['langcode'] = array(
-      '#title' => t('Language'),
-      '#type' => 'language_select',
-      '#default_value' => $default_language,
-      '#languages' => Language::STATE_ALL,
-      '#access' => !empty($language_configuration['language_show']),
-    );
-
     $default = $this->entity->getMenuName() . ':' . $this->entity->getParentId();
     $form['menu_parent'] = $this->menuParentSelector->parentSelectElement($default, $this->entity->getPluginId());
     $form['menu_parent']['#weight'] = 10;
diff --git a/core/modules/menu_ui/src/Tests/MenuLanguageTest.php b/core/modules/menu_ui/src/Tests/MenuLanguageTest.php
index f74fb09..0664b81 100644
--- a/core/modules/menu_ui/src/Tests/MenuLanguageTest.php
+++ b/core/modules/menu_ui/src/Tests/MenuLanguageTest.php
@@ -105,7 +105,7 @@ function testMenuLanguage() {
 
     // Now change the language of the new link to 'bb'.
     $edit = array(
-      'langcode' => 'bb',
+      'langcode[0][value]' => 'bb',
     );
     $this->drupalPostForm('admin/structure/menu/item/' . $menu_link->id() . '/edit', $edit, t('Save'));
     $this->assertMenuLink($menu_link->getPluginId(), array(
@@ -119,14 +119,14 @@ function testMenuLanguage() {
     // page first.
     $this->drupalGet('admin/structure/menu/item/' . $menu_link->id() . '/edit');
     // Check that the language selector has the correct default value.
-    $this->assertOptionSelected('edit-langcode', 'bb', 'The menu link language was correctly selected.');
+    $this->assertOptionSelected('edit-langcode-0-value', 'bb', 'The menu link language was correctly selected.');
 
     // Edit menu to hide the language select on menu link item add.
      language_save_default_configuration('menu_link_content', 'menu_link_content',  array('langcode' => 'cc', 'language_show' => FALSE));
 
     // Check that the language selector is not available on menu link add page.
     $this->drupalGet("admin/structure/menu/manage/$menu_name/add");
-    $this->assertNoField('edit-langcode', 'The language selector field was hidden the page');
+    $this->assertNoField('edit-langcode-0-value', 'The language selector field was hidden the page');
   }
 
   /**
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 1aa4a2a..957e9d7 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -373,30 +373,8 @@ function node_add_body_field(NodeTypeInterface $type, $label = 'Body') {
  */
 function node_entity_extra_field_info() {
   $extra = array();
-  $module_language_enabled = \Drupal::moduleHandler()->moduleExists('language');
   $description = t('Node module element');
-
   foreach (node_type_get_types() as $bundle) {
-    // Add the 'language' select if Language module is enabled and the bundle
-    // has multilingual support.
-    // Visibility of the ordering of the language selector is the same as on the
-    // node/add form.
-    if ($module_language_enabled) {
-      $configuration = language_get_default_configuration('node', $bundle->type);
-      if ($configuration['language_show']) {
-        $extra['node'][$bundle->type]['form']['langcode'] = array(
-          'label' => t('Language'),
-          'description' => $description,
-          'weight' => 0,
-        );
-      }
-    }
-    $extra['node'][$bundle->type]['display']['langcode'] = array(
-      'label' => t('Language'),
-      'description' => $description,
-      'weight' => 0,
-      'visible' => FALSE,
-    );
     $extra['node'][$bundle->type]['display']['links'] = array(
       'label' => t('Links'),
       'description' => $description,
diff --git a/core/modules/node/src/Entity/Node.php b/core/modules/node/src/Entity/Node.php
index 5948103..8c271b1 100644
--- a/core/modules/node/src/Entity/Node.php
+++ b/core/modules/node/src/Entity/Node.php
@@ -347,9 +347,13 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setReadOnly(TRUE);
 
     $fields['langcode'] = BaseFieldDefinition::create('language')
-      ->setLabel(t('Language code'))
+      ->setLabel(t('Language'))
       ->setDescription(t('The node language code.'))
-      ->setRevisionable(TRUE);
+      ->setRevisionable(TRUE)
+      ->setDisplayOptions('form', array(
+        'type' => 'language_select',
+        'weight' => 2,
+      ));
 
     $fields['title'] = BaseFieldDefinition::create('string')
       ->setLabel(t('Title'))
diff --git a/core/modules/node/src/NodeForm.php b/core/modules/node/src/NodeForm.php
index 7f9ef84..790462f 100644
--- a/core/modules/node/src/NodeForm.php
+++ b/core/modules/node/src/NodeForm.php
@@ -108,15 +108,6 @@ public function form(array $form, FormStateInterface $form_state) {
       '#default_value' => $node->getChangedTime(),
     );
 
-    $language_configuration = \Drupal::moduleHandler()->invoke('language', 'get_default_configuration', array('node', $node->getType()));
-    $form['langcode'] = array(
-      '#title' => t('Language'),
-      '#type' => 'language_select',
-      '#default_value' => $node->getUntranslated()->language()->getId(),
-      '#languages' => LanguageInterface::STATE_ALL,
-      '#access' => isset($language_configuration['language_show']) && $language_configuration['language_show'],
-    );
-
     $form['advanced'] = array(
       '#type' => 'vertical_tabs',
       '#attributes' => array('class' => array('entity-meta')),
diff --git a/core/modules/node/src/Tests/NodeFieldMultilingualTest.php b/core/modules/node/src/Tests/NodeFieldMultilingualTest.php
index d00ffcd..1e2c731 100644
--- a/core/modules/node/src/Tests/NodeFieldMultilingualTest.php
+++ b/core/modules/node/src/Tests/NodeFieldMultilingualTest.php
@@ -84,7 +84,7 @@ function testMultilingualNodeForm() {
     $this->drupalGet("node/{$node->id()}/edit");
     $edit = array(
       $title_key => $this->randomMachineName(8),
-      'langcode' => $langcode,
+      'langcode[0][value]' => $langcode,
     );
     $this->drupalPostForm(NULL, $edit, t('Save'));
     $node = $this->drupalGetNodeByTitle($edit[$title_key], TRUE);
diff --git a/core/modules/node/src/Tests/NodeTranslationUITest.php b/core/modules/node/src/Tests/NodeTranslationUITest.php
index b5fd27a..1dfb855 100644
--- a/core/modules/node/src/Tests/NodeTranslationUITest.php
+++ b/core/modules/node/src/Tests/NodeTranslationUITest.php
@@ -78,22 +78,6 @@ protected function getNewEntityValues($langcode) {
   /**
    * {@inheritdoc}
    */
-  protected function createEntity($values, $langcode, $bundle_name = NULL) {
-    $this->drupalLogin($this->editor);
-    $edit = array(
-      'title[0][value]' => $values['title'][0]['value'],
-      "{$this->fieldName}[0][value]" => $values[$this->fieldName][0]['value'],
-      'langcode' => $langcode,
-    );
-    $this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
-    $this->drupalLogin($this->translator);
-    $node = $this->drupalGetNodeByTitle($values['title']);
-    return $node->id();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   protected function getFormSubmitAction(EntityInterface $entity, $langcode) {
     if ($entity->getTranslation($langcode)->isPublished()) {
       return t('Save and keep published') . $this->getFormSubmitSuffix($entity, $langcode);
diff --git a/core/modules/node/src/Tests/NodeTypeInitialLanguageTest.php b/core/modules/node/src/Tests/NodeTypeInitialLanguageTest.php
index 971d091..6b2f538 100644
--- a/core/modules/node/src/Tests/NodeTypeInitialLanguageTest.php
+++ b/core/modules/node/src/Tests/NodeTypeInitialLanguageTest.php
@@ -66,8 +66,8 @@ function testNodeTypeInitialLanguageDefaults() {
     );
     $this->drupalPostForm('admin/structure/types/manage/article', $edit, t('Save content type'));
     $this->drupalGet('node/add/article');
-    $this->assertField('langcode', 'Language is selectable on node add/edit page when language not hidden.');
-    $this->assertOptionSelected('edit-langcode', 'hu', 'The initial language is the site default on the node add page after the site default language is changed.');
+    $this->assertField('langcode[0][value]', 'Language is selectable on node add/edit page when language not hidden.');
+    $this->assertOptionSelected('edit-langcode-0-value', 'hu', 'The initial language is the site default on the node add page after the site default language is changed.');
 
     // Tests if the language field can be rearranged on the manage form display
     // tab.
@@ -75,20 +75,13 @@ function testNodeTypeInitialLanguageDefaults() {
     $language_field = $this->xpath('//*[@id="langcode"]');
     $this->assert(!empty($language_field), 'Language field is visible on manage form display tab.');
 
-    // Tests if the language field can be rearranged on the manage display tab.
-    $this->drupalGet('admin/structure/types/manage/article/display');
-    $language_display = $this->xpath('//*[@id="langcode"]');
-    $this->assert(!empty($language_display), 'Language field is visible on manage display tab.');
-    // Tests if the language field is hidden by default.
-    $this->assertOptionSelected('edit-fields-langcode-type', 'hidden', 'Language is hidden by default on manage display tab.');
-
     // Changes the initial language settings.
     $edit = array(
       'language_configuration[langcode]' => 'en',
     );
     $this->drupalPostForm('admin/structure/types/manage/article', $edit, t('Save content type'));
     $this->drupalGet('node/add/article');
-    $this->assertOptionSelected('edit-langcode', 'en', 'The initial language is the defined language.');
+    $this->assertOptionSelected('edit-langcode-0-value', 'en', 'The initial language is the defined language.');
   }
 
   /**
@@ -110,20 +103,5 @@ function testLanguageFieldVisibility() {
       ':id' => 'field-language-display',
     ));
     $this->assertTrue(empty($language_field), 'Language field value is not shown by default on node page.');
-
-    // Changes Language field visibility to true and check if it is saved.
-    $edit = array(
-      'fields[langcode][type]' => 'visible',
-    );
-    $this->drupalPostForm('admin/structure/types/manage/article/display', $edit, t('Save'));
-    $this->drupalGet('admin/structure/types/manage/article/display');
-    $this->assertOptionSelected('edit-fields-langcode-type', 'visible', 'Language field has been set to visible.');
-
-    // Loads node page and check if Language field is shown.
-    $this->drupalGet('node/' . $node->id());
-    $language_field = $this->xpath('//div[@id=:id]/div', array(
-      ':id' => 'field-language-display',
-    ));
-    $this->assertFalse(empty($language_field), 'Language field value is shown on node page.');
   }
 }
diff --git a/core/modules/shortcut/src/Entity/Shortcut.php b/core/modules/shortcut/src/Entity/Shortcut.php
index 770406a..fc27f25 100644
--- a/core/modules/shortcut/src/Entity/Shortcut.php
+++ b/core/modules/shortcut/src/Entity/Shortcut.php
@@ -213,8 +213,12 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setDescription(t('A serialized array of route parameters of this shortcut.'));
 
     $fields['langcode'] = BaseFieldDefinition::create('language')
-      ->setLabel(t('Language code'))
-      ->setDescription(t('The language code of the shortcut.'));
+      ->setLabel(t('Language'))
+      ->setDescription(t('The language code of the shortcut.'))
+      ->setDisplayOptions('form', array(
+        'type' => 'language_select',
+        'weight' => 2,
+      ));
 
     $fields['path'] = BaseFieldDefinition::create('string')
       ->setLabel(t('Path'))
diff --git a/core/modules/shortcut/src/ShortcutForm.php b/core/modules/shortcut/src/ShortcutForm.php
index 86c022e..ee53837 100644
--- a/core/modules/shortcut/src/ShortcutForm.php
+++ b/core/modules/shortcut/src/ShortcutForm.php
@@ -69,13 +69,6 @@ public function form(array $form, FormStateInterface $form_state) {
       '#default_value' => $this->entity->path->value,
     );
 
-    $form['langcode'] = array(
-      '#title' => t('Language'),
-      '#type' => 'language_select',
-      '#default_value' => $this->entity->getUntranslated()->language()->getId(),
-      '#languages' => LanguageInterface::STATE_ALL,
-    );
-
     return $form;
   }
 
diff --git a/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php b/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php
index 59da34d..b3e3351 100644
--- a/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php
+++ b/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php
@@ -89,7 +89,7 @@ function testEntityFormLanguage() {
     $langcode = $this->langcodes[0];
     $edit['title[0][value]'] = $this->randomMachineName(8);
     $edit['body[0][value]'] = $this->randomMachineName(16);
-    $edit['langcode'] = $langcode;
+    $edit['langcode[0][value]'] = $langcode;
     $this->drupalPostForm('node/add/page', $edit, t('Save'));
     $this->assertRaw(t('Basic page %title has been created.', array('%title' => $edit['title[0][value]'])), 'Basic page created.');
 
diff --git a/core/modules/system/tests/modules/entity_test/src/EntityTestForm.php b/core/modules/system/tests/modules/entity_test/src/EntityTestForm.php
index 8a60fef..ec7c3e0 100644
--- a/core/modules/system/tests/modules/entity_test/src/EntityTestForm.php
+++ b/core/modules/system/tests/modules/entity_test/src/EntityTestForm.php
@@ -35,13 +35,6 @@ public function form(array $form, FormStateInterface $form_state) {
     $form = parent::form($form, $form_state);
     $entity = $this->entity;
 
-    $form['langcode'] = array(
-      '#title' => t('Language'),
-      '#type' => 'language_select',
-      '#default_value' => $entity->getUntranslated()->language()->getId(),
-      '#languages' => LanguageInterface::STATE_ALL,
-    );
-
     // @todo: Is there a better way to check if an entity type is revisionable?
     if ($entity->getEntityType()->hasKey('revision') && !$entity->isNew()) {
       $form['revision'] = array(
diff --git a/core/modules/taxonomy/src/Entity/Term.php b/core/modules/taxonomy/src/Entity/Term.php
index caebc53..047f5ad 100644
--- a/core/modules/taxonomy/src/Entity/Term.php
+++ b/core/modules/taxonomy/src/Entity/Term.php
@@ -118,8 +118,12 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setSetting('target_type', 'taxonomy_vocabulary');
 
     $fields['langcode'] = BaseFieldDefinition::create('language')
-      ->setLabel(t('Language code'))
-      ->setDescription(t('The term language code.'));
+      ->setLabel(t('Language'))
+      ->setDescription(t('The term language code.'))
+      ->setDisplayOptions('form', array(
+        'type' => 'language_select',
+        'weight' => 2,
+      ));
 
     $fields['name'] = BaseFieldDefinition::create('string')
       ->setLabel(t('Name'))
diff --git a/core/modules/taxonomy/src/TermForm.php b/core/modules/taxonomy/src/TermForm.php
index 2136b0f..8cee383 100644
--- a/core/modules/taxonomy/src/TermForm.php
+++ b/core/modules/taxonomy/src/TermForm.php
@@ -28,15 +28,6 @@ public function form(array $form, FormStateInterface $form_state) {
     $form_state->set(['taxonomy', 'parent'], $parent);
     $form_state->set(['taxonomy', 'vocabulary'], $vocabulary);
 
-    $language_configuration = $this->moduleHandler->moduleExists('language') ? language_get_default_configuration('taxonomy_term', $vocabulary->id()) : FALSE;
-    $form['langcode'] = array(
-      '#type' => 'language_select',
-      '#title' => $this->t('Language'),
-      '#languages' => LanguageInterface::STATE_ALL,
-      '#default_value' => $term->getUntranslated()->language()->getId(),
-      '#access' => !empty($language_configuration['language_show']),
-    );
-
     $form['relations'] = array(
       '#type' => 'details',
       '#title' => $this->t('Relations'),
diff --git a/core/modules/taxonomy/src/Tests/TermLanguageTest.php b/core/modules/taxonomy/src/Tests/TermLanguageTest.php
index 71cacee..0504751 100644
--- a/core/modules/taxonomy/src/Tests/TermLanguageTest.php
+++ b/core/modules/taxonomy/src/Tests/TermLanguageTest.php
@@ -48,28 +48,28 @@ function testTermLanguage() {
     // Add a term.
     $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add');
     // Check that we have the language selector.
-    $this->assertField('edit-langcode', t('The language selector field was found on the page.'));
+    $this->assertField('edit-langcode-0-value', t('The language selector field was found on the page.'));
     // Submit the term.
     $edit = array(
       'name[0][value]' => $this->randomMachineName(),
-      'langcode' => 'aa',
+      'langcode[0][value]' => 'aa',
     );
     $this->drupalPostForm(NULL, $edit, t('Save'));
     $terms = taxonomy_term_load_multiple_by_name($edit['name[0][value]']);
     $term = reset($terms);
-    $this->assertEqual($term->language()->getId(), $edit['langcode'], 'The term contains the correct langcode.');
+    $this->assertEqual($term->language()->getId(), $edit['langcode[0][value]'], 'The term contains the correct langcode.');
 
     // Check if on the edit page the language is correct.
     $this->drupalGet('taxonomy/term/' . $term->id() . '/edit');
-    $this->assertOptionSelected('edit-langcode', $edit['langcode'], 'The term language was correctly selected.');
+    $this->assertOptionSelected('edit-langcode-0-value', $edit['langcode[0][value]'], 'The term language was correctly selected.');
 
     // Change the language of the term.
-    $edit['langcode'] = 'bb';
+    $edit['langcode[0][value]'] = 'bb';
     $this->drupalPostForm('taxonomy/term/' . $term->id() . '/edit', $edit, t('Save'));
 
     // Check again that on the edit page the language is correct.
     $this->drupalGet('taxonomy/term/' . $term->id() . '/edit');
-    $this->assertOptionSelected('edit-langcode', $edit['langcode'], 'The term language was correctly selected.');
+    $this->assertOptionSelected('edit-langcode-0-value', $edit['langcode[0][value]'], 'The term language was correctly selected.');
   }
 
   function testDefaultTermLanguage() {
@@ -81,7 +81,7 @@ function testDefaultTermLanguage() {
     );
     $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id(), $edit, t('Save'));
     $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add');
-    $this->assertOptionSelected('edit-langcode', 'bb', 'The expected langcode was selected.');
+    $this->assertOptionSelected('edit-langcode-0-value', 'bb', 'The expected langcode was selected.');
 
     // Make the default language of the terms to be the current interface.
     $edit = array(
@@ -90,9 +90,9 @@ function testDefaultTermLanguage() {
     );
     $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id(), $edit, t('Save'));
     $this->drupalGet('aa/admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add');
-    $this->assertOptionSelected('edit-langcode', 'aa', "The expected langcode, 'aa', was selected.");
+    $this->assertOptionSelected('edit-langcode-0-value', 'aa', "The expected langcode, 'aa', was selected.");
     $this->drupalGet('bb/admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add');
-    $this->assertOptionSelected('edit-langcode', 'bb', "The expected langcode, 'bb', was selected.");
+    $this->assertOptionSelected('edit-langcode-0-value', 'bb', "The expected langcode, 'bb', was selected.");
 
     // Change the default language of the site and check if the default terms
     // language is still correctly selected.
@@ -103,6 +103,6 @@ function testDefaultTermLanguage() {
     );
     $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id(), $edit, t('Save'));
     $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add');
-    $this->assertOptionSelected('edit-langcode', 'cc', "The expected langcode, 'cc', was selected.");
+    $this->assertOptionSelected('edit-langcode-0-value', 'cc', "The expected langcode, 'cc', was selected.");
   }
 }
