diff --git a/core/config/schema/core.entity.schema.yml b/core/config/schema/core.entity.schema.yml
index f6442f7..46099cd 100644
--- a/core/config/schema/core.entity.schema.yml
+++ b/core/config/schema/core.entity.schema.yml
@@ -232,6 +232,13 @@ field.formatter.settings.string:
       type: boolean
       label: 'Link to the entity'
 
+field.formatter.settings.language:
+  type: field.formatter.settings.string
+  mapping:
+    native_name:
+      type: boolean
+      label: 'Display in native language'
+
 field.formatter.settings.number_decimal:
   type: mapping
   label: 'Number decimal display format settings'
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/LanguageFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/LanguageFormatter.php
index d936b89..20b23a2 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/LanguageFormatter.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/LanguageFormatter.php
@@ -8,8 +8,9 @@
 namespace Drupal\Core\Field\Plugin\Field\FieldFormatter;
 
 use Drupal\Component\Utility\String;
-use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Field\FieldItemInterface;
 use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Form\FormStateInterface;
 
 /**
  * Plugin implementation of the 'language' formatter.
@@ -22,19 +23,52 @@
  *   }
  * )
  */
-class LanguageFormatter extends FormatterBase {
+class LanguageFormatter extends StringFormatter {
 
   /**
    * {@inheritdoc}
    */
-  public function viewElements(FieldItemListInterface $items) {
-    $elements = array();
+  public static function defaultSettings() {
+    $settings = parent::defaultSettings();
+    $settings['native_name'] = FALSE;
+    return $settings;
+  }
 
-    foreach ($items as $delta => $item) {
-      $elements[$delta] = array('#markup' => $item->language ? String::checkPlain($item->language->getName()) : '');
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, FormStateInterface $form_state) {
+    $form = parent::settingsForm($form, $form_state);
+    $form['native_name'] = array(
+      '#title' => $this->t('Display in native language'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->getSetting('native_name'),
+    );
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = parent::settingsSummary();
+    if ($this->getSetting('native_name')) {
+      $additional_summary = $this->t('Displayed in native name');
+      if (!empty($summary['#markup'])) {
+        $summary['#markup'] .= '; ' . $additional_summary;
+      }
+      else {
+        $summary['#markup'] = $additional_summary;
+      }
     }
+  }
 
-    return $elements;
+  /**
+   * {@inheritdoc}
+   */
+  protected function viewValue(FieldItemInterface $item) {
+    $languages = $languages = $this->getSetting('native_name') ? \Drupal::languageManager()->getNativeLanguages() : \Drupal::languageManager()->getLanguages();
+    return $item->language ? String::checkPlain($languages[$item->language->getId()]->getName()) : '';
   }
 
 }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php
index ec9b79d..5949528 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php
@@ -10,6 +10,7 @@
 use Drupal\Component\Utility\String;
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FieldItemInterface;
 use Drupal\Core\Field\FormatterBase;
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Form\FormStateInterface;
@@ -127,7 +128,7 @@ public function viewElements(FieldItemListInterface $items) {
     foreach ($items as $delta => $item) {
       // The text value has no text format assigned to it, so the user input
       // should equal the output, including newlines.
-      $string = nl2br(String::checkPlain($item->value));
+      $string = $this->viewValue($item);
 
       if ($url) {
         $elements[$delta] = [
@@ -144,4 +145,17 @@ public function viewElements(FieldItemListInterface $items) {
     return $elements;
   }
 
+  /**
+   * Generate the output appropriate for one field item.
+   *
+   * @param \Drupal\Core\Field\FieldItemInterface $item
+   *   One field item.
+   *
+   * @return string
+   *   The textual output generated.
+   */
+  protected function viewValue(FieldItemInterface $item) {
+    return nl2br(String::checkPlain($item->value));
+  }
+
 }
diff --git a/core/modules/field/config/schema/field.views.schema.yml b/core/modules/field/config/schema/field.views.schema.yml
index 56d852d..9c625f5 100644
--- a/core/modules/field/config/schema/field.views.schema.yml
+++ b/core/modules/field/config/schema/field.views.schema.yml
@@ -18,7 +18,7 @@ views.argument.field_list_string:
 
 views.field.field:
   type: views_field
-  label: 'Log event message'
+  label: 'Views field field handler'
   mapping:
     click_sort_column:
       type: string
@@ -27,11 +27,8 @@ views.field.field:
       type: string
       label: 'Formatter'
     settings:
-      type: sequence
+      type: field.formatter.settings.[%parent.type]
       label: 'Settings'
-      sequence:
-        - type: string
-          label: 'Setting'
     group_column:
       type: string
       label: 'Group by column'
diff --git a/core/modules/node/config/schema/node.views.schema.yml b/core/modules/node/config/schema/node.views.schema.yml
index b1d24d9..a8e4cfa 100644
--- a/core/modules/node/config/schema/node.views.schema.yml
+++ b/core/modules/node/config/schema/node.views.schema.yml
@@ -93,14 +93,6 @@ views.argument_validator.node:
       type: string
       label: 'Filter value format'
 
-views.field.node_language:
-  type: views.field.node
-  label: 'Node language'
-  mapping:
-    native_language:
-      type: boolean
-      label: 'Native language'
-
 views.field.node:
   type: views_field
   label: 'Node'
diff --git a/core/modules/node/src/NodeViewsData.php b/core/modules/node/src/NodeViewsData.php
index ca2bb26..d7f97c5 100644
--- a/core/modules/node/src/NodeViewsData.php
+++ b/core/modules/node/src/NodeViewsData.php
@@ -40,7 +40,6 @@ public function getViewsData() {
     $data['node_field_data']['type']['argument']['id'] = 'node_type';
 
     $data['node_field_data']['langcode']['help'] = t('The language of the content or translation.');
-    $data['node_field_data']['langcode']['field']['id'] = 'node_language';
 
     $data['node_field_data']['status']['field']['output formats'] = [
       'published-notpublished' => array(t('Published'), t('Not published')),
@@ -290,7 +289,6 @@ public function getViewsData() {
     ) + $data['node_revision']['vid'];
 
     $data['node_revision']['langcode']['help'] = t('The language the original content is in.');
-    $data['node_revision']['langcode']['field']['id'] = 'node_language';
 
     $data['node_revision']['revision_log']['field']['id'] = 'xss';
 
@@ -312,7 +310,6 @@ public function getViewsData() {
     $data['node_field_revision']['title']['field']['id'] = 'node_revision';
 
     $data['node_field_revision']['langcode']['help'] = t('The language of the content or translation.');
-    $data['node_field_revision']['langcode']['field']['id'] = 'node_language';
 
     $data['node_revision']['link_to_revision'] = array(
       'field' => array(
diff --git a/core/modules/node/src/Plugin/views/field/Language.php b/core/modules/node/src/Plugin/views/field/Language.php
deleted file mode 100644
index 9e55ce9..0000000
--- a/core/modules/node/src/Plugin/views/field/Language.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\node\Plugin\views\field\Language.
- */
-
-namespace Drupal\node\Plugin\views\field;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\node\Plugin\views\field\Node;
-use Drupal\views\ResultRow;
-
-/**
- * Field handler to translate a language into its readable form.
- *
- * @ingroup views_field_handlers
- *
- * @ViewsField("node_language")
- */
-class Language extends Node {
-
-  protected function defineOptions() {
-    $options = parent::defineOptions();
-    $options['native_language'] = array('default' => FALSE);
-
-    return $options;
-  }
-
-  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
-    parent::buildOptionsForm($form, $form_state);
-    $form['native_language'] = array(
-      '#title' => $this->t('Native language'),
-      '#type' => 'checkbox',
-      '#default_value' => $this->options['native_language'],
-      '#description' => $this->t('If enabled, the native name of the language will be displayed'),
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function render(ResultRow $values) {
-    // @todo: Drupal Core dropped native language until config translation is
-    // ready, see http://drupal.org/node/1616594.
-    $value = $this->getValue($values);
-    $language = language_load($value);
-    $value = $language ? $language->getName() : '';
-    return $this->renderLink($value, $values);
-  }
-
-}
diff --git a/core/modules/node/src/Tests/Views/NodeLanguageTest.php b/core/modules/node/src/Tests/Views/NodeLanguageTest.php
index 0195b44..ce73aae 100644
--- a/core/modules/node/src/Tests/Views/NodeLanguageTest.php
+++ b/core/modules/node/src/Tests/Views/NodeLanguageTest.php
@@ -226,4 +226,52 @@ public function testLanguages() {
       }
     }
   }
+
+  /**
+   * Tests native name display in language field.
+   */
+  public function testNativeLanguageField() {
+    $this->assertLanguageNames();
+
+    // Modify test view to display native language names and set translations.
+    $config = \Drupal::config('views.view.test_language');
+    $config->set('display.default.display_options.fields.langcode.settings.native_name', TRUE);
+    $config->save();
+    \Drupal::languageManager()->getLanguageConfigOverride('fr', 'language.entity.fr')->set('label', 'Français')->save();
+    \Drupal::languageManager()->getLanguageConfigOverride('es', 'language.entity.es')->set('label', 'Español')->save();
+    $this->assertLanguageNames(TRUE);
+
+    // Modify test view to use the views built-in language field and test that.
+    $config = \Drupal::config('views.view.test_language');
+    $config->set('display.default.display_options.fields.langcode.native_name', FALSE);
+    $config->clear('display.default.display_options.fields.langcode.settings');
+    $config->set('display.default.display_options.fields.langcode.plugin_id', 'language');
+    $config->save();
+    $this->assertLanguageNames();
+    $config->set('display.default.display_options.fields.langcode.native_name', TRUE)->save();
+    $this->assertLanguageNames(TRUE);
+  }
+
+  /**
+   * Assert the presence of language names in their English or native forms.
+   *
+   * @param bool $native
+   *   (optional) Whether to assert the language name in its native form.
+   */
+  protected function assertLanguageNames($native = FALSE) {
+    $this->drupalGet('test-language');
+    if ($native) {
+      $this->assertText('Français', 'French language shown translated.');
+      $this->assertText('Español', 'Spanish language shown translated.');
+      $this->assertNoText('French', 'French language not shown in English.');
+      $this->assertNoText('Spanish', 'Spanish language not shown in English.');
+    }
+    else {
+      $this->assertNoText('Français', 'French language not shown translated.');
+      $this->assertNoText('Español', 'Spanish language not shown translated.');
+      $this->assertText('French', 'French language shown in English.');
+      $this->assertText('Spanish', 'Spanish language shown in English.');
+    }
+  }
+
 }
diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml
index 462d371..8490cb3 100644
--- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml
+++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml
@@ -159,11 +159,11 @@ display:
           hide_empty: false
           empty_zero: false
           hide_alter_empty: true
-          link_to_node: false
-          native_language: false
-          plugin_id: node_language
+          plugin_id: field
           entity_type: node
           entity_field: langcode
+          settings:
+            native_name: false
       filters:
         status:
           value: true
@@ -223,8 +223,7 @@ display:
             default_group: All
             default_group_multiple: {  }
             group_items: {  }
-          plugin_id: language
-          entity_type: node
+          pluplugin_id: field        entity_type: node
           entity_field: langcode
       sorts:
         langcode:
diff --git a/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml b/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml
index d64639e..cf80f28 100644
--- a/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml
+++ b/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml
@@ -83,10 +83,6 @@ views.argument_default.taxonomy_tid:
       type: string
       label: 'Multiple-value handling'
 
-views.field.taxonomy_term_language:
-  type: views.field.taxonomy
-  label: 'Taxonomy language'
-
 views.field.term_link_edit:
   type: views_field
   label: 'Taxonomy language'
diff --git a/core/modules/taxonomy/src/Plugin/views/field/Language.php b/core/modules/taxonomy/src/Plugin/views/field/Language.php
deleted file mode 100644
index 3fbc0b8..0000000
--- a/core/modules/taxonomy/src/Plugin/views/field/Language.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\taxonomy\Plugin\views\field\Language.
- */
-
-namespace Drupal\taxonomy\Plugin\views\field;
-
-use Drupal\views\ResultRow;
-
-/**
- * Field handler to show the language of a taxonomy term.
- *
- * @ViewsField("taxonomy_term_language")
- */
-class Language extends Taxonomy {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function render(ResultRow $values) {
-    $value = $this->getValue($values);
-    $language = \Drupal::languageManager()->getLanguage($value);
-    $value = $language ? $language->getName() : '';
-
-    return $this->renderLink($this->sanitizeValue($value), $values);
-  }
-
-}
diff --git a/core/modules/taxonomy/src/TermViewsData.php b/core/modules/taxonomy/src/TermViewsData.php
index 4b4e578..ca88036 100644
--- a/core/modules/taxonomy/src/TermViewsData.php
+++ b/core/modules/taxonomy/src/TermViewsData.php
@@ -100,8 +100,6 @@ public function getViewsData() {
 
     $data['taxonomy_term_field_data']['description__value']['field']['click sortable'] = FALSE;
 
-    $data['taxonomy_term_field_data']['langcode']['field']['id'] = 'taxonomy_term_language';
-
     $data['taxonomy_term_field_data']['changed']['title'] = t('Updated date');
     $data['taxonomy_term_field_data']['changed']['help'] = t('The date the term was last updated.');
 
diff --git a/core/modules/user/config/schema/user.views.schema.yml b/core/modules/user/config/schema/user.views.schema.yml
index e1b83f3..46cb281 100644
--- a/core/modules/user/config/schema/user.views.schema.yml
+++ b/core/modules/user/config/schema/user.views.schema.yml
@@ -67,10 +67,6 @@ views_field_user:
       type: boolean
       label: 'Link this field to its user'
 
-views.field.user_language:
-  type: views_field_user
-  label: 'User language'
-
 views.field.user_link:
   type: views_field
   label: 'User link'
diff --git a/core/modules/user/src/Plugin/views/field/Language.php b/core/modules/user/src/Plugin/views/field/Language.php
deleted file mode 100644
index 7e7c0ed..0000000
--- a/core/modules/user/src/Plugin/views/field/Language.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\user\Plugin\views\field\Language.
- */
-
-namespace Drupal\user\Plugin\views\field;
-
-use Drupal\views\ResultRow;
-
-/**
- * Views field handler for user language.
- *
- * @ingroup views_field_handlers
- *
- * @ViewsField("user_language")
- */
-class Language extends User {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function renderLink($data, ResultRow $values) {
-    if (!empty($this->options['link_to_user'])) {
-      $uid = $this->getValue($values, 'uid');
-      if ($this->view->getUser()->hasPermission('access user profiles') && $uid) {
-        $this->options['alter']['make_link'] = TRUE;
-        $this->options['alter']['path'] = 'user/' . $uid;
-      }
-    }
-    if (empty($data)) {
-      $lang = language_default();
-    }
-    else {
-      $lang = \Drupal::languageManager()->getLanguages();
-      $lang = $lang[$data];
-    }
-
-    return $this->sanitizeValue($lang->getName());
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function render(ResultRow $values) {
-    $value = $this->getValue($values);
-    return $this->renderLink($this->sanitizeValue($value), $values);
-  }
-
-}
diff --git a/core/modules/user/src/UserViewsData.php b/core/modules/user/src/UserViewsData.php
index acf2100..3c46c35 100644
--- a/core/modules/user/src/UserViewsData.php
+++ b/core/modules/user/src/UserViewsData.php
@@ -88,7 +88,6 @@ public function getViewsData() {
     $data['users_field_data']['mail']['help'] = t('Email address for a given user. This field is normally not shown to users, so be cautious when using it.');
     $data['users_field_data']['mail']['field']['id'] = 'user_mail';
 
-    $data['users']['langcode']['id'] = 'user_language';
     $data['users']['langcode']['help'] = t('Original language of the user information');
     $data['users_field_data']['langcode']['help'] = t('Language of the translation of user information');
 
diff --git a/core/modules/views/config/schema/views.field.schema.yml b/core/modules/views/config/schema/views.field.schema.yml
index c515361..e911171 100644
--- a/core/modules/views/config/schema/views.field.schema.yml
+++ b/core/modules/views/config/schema/views.field.schema.yml
@@ -178,3 +178,7 @@ views.field.xss:
 views.field.language:
   type: views_field
   label: 'Language'
+  mapping:
+    native_name:
+      type: boolean
+      label: 'Display in native language'
diff --git a/core/modules/views/src/EntityViewsData.php b/core/modules/views/src/EntityViewsData.php
index cb30422..91ad27c 100644
--- a/core/modules/views/src/EntityViewsData.php
+++ b/core/modules/views/src/EntityViewsData.php
@@ -300,7 +300,7 @@ protected function mapSingleFieldViewsData($table, $field_name, $field_type, $co
         break;
 
       case 'language':
-        $views_field['field']['id'] = 'language';
+        $views_field['field']['id'] = 'field';
         $views_field['argument']['id'] = 'language';
         $views_field['filter']['id'] = 'language';
         $views_field['sort']['id'] = 'standard';
diff --git a/core/modules/views/src/Plugin/views/field/LanguageField.php b/core/modules/views/src/Plugin/views/field/LanguageField.php
index 5792bd0..68a5d26 100644
--- a/core/modules/views/src/Plugin/views/field/LanguageField.php
+++ b/core/modules/views/src/Plugin/views/field/LanguageField.php
@@ -19,20 +19,25 @@
  */
 class LanguageField extends FieldPluginBase {
 
+  /**
+   * {@inheritdoc}
+   */
   protected function defineOptions() {
     $options = parent::defineOptions();
-    $options['native_language'] = array('default' => FALSE);
+    $options['native_name'] = array('default' => FALSE);
 
     return $options;
   }
 
+  /**
+   * {@inheritdoc}
+   */
   public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     parent::buildOptionsForm($form, $form_state);
-    $form['native_language'] = array(
-      '#title' => $this->t('Native language'),
+    $form['native_name'] = array(
+      '#title' => $this->t('Display in native language'),
       '#type' => 'checkbox',
-      '#default_value' => $this->options['native_language'],
-      '#description' => $this->t('If enabled, the native name of the language will be displayed'),
+      '#default_value' => $this->options['native_name'],
     );
   }
 
@@ -40,11 +45,9 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function render(ResultRow $values) {
-    // @todo: Drupal Core dropped native language until config translation is
-    // ready, see http://drupal.org/node/1616594.
     $value = $this->getValue($values);
-    $language = language_load($value);
-    return $language ? $language->getName() : '';
+    $languages = $this->options['native_name'] ? \Drupal::languageManager()->getNativeLanguages() : \Drupal::languageManager()->getLanguages();
+    return isset($languages[$value]) ? $languages[$value]->getName() : '';
   }
 
 }
