diff --git a/core/modules/language/language.views.inc b/core/modules/language/language.views.inc
new file mode 100644
index 0000000000000000000000000000000000000000..2ec7e3a0b7cc67dc7703818d9ff6cd6b02002b49
--- /dev/null
+++ b/core/modules/language/language.views.inc
@@ -0,0 +1,108 @@
+<?php
+
+/**
+ * @file
+ * Provide views data and handlers for language.module.
+ *
+ * @ingroup views_module_handlers
+ */
+
+/**
+ * Implements hook_views_data().
+ */
+function language_views_data() {
+  $data['language']['table']['group']  = t('Language');
+
+  $data['language']['table']['base'] = array(
+    'field' => 'langcode',
+    'title' => t('Language'),
+    'help' => t('A language used in drupal.'),
+  );
+
+  $data['language']['langcode'] = array(
+    'title' => t('Language code'),
+    'help' => t("Language code, e.g. 'de' or 'en-US'."),
+    'field' => array(
+      'id' => 'standard',
+    ),
+    'filter' => array(
+      'id' => 'string'
+    ),
+    'argument' => array(
+      'id' => 'string',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+  );
+
+  $data['language']['name'] = array(
+    'title' => t('Language name'),
+    'help' => t("Language name, e.g. 'German' or 'English'."),
+    'field' => array(
+      'id' => 'standard',
+    ),
+    'filter' => array(
+      'id' => 'string'
+    ),
+    'argument' => array(
+      'id' => 'string',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+  );
+
+  $data['language']['direction'] = array(
+    'title' => t('Direction'),
+    'help' => t('Direction of language (Left-to-Right = 0, Right-to-Left = 1).'),
+    'field' => array(
+      'id' => 'numeric',
+    ),
+    'filter' => array(
+      'id' => 'numeric'
+    ),
+    'argument' => array(
+      'id' => 'numeric',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+  );
+
+  $data['language']['weight'] = array(
+    'title' => t('Weight'),
+    'help' => t('Weight, used in lists of languages.'),
+    'field' => array(
+      'id' => 'numeric',
+    ),
+    'filter' => array(
+      'id' => 'numeric'
+    ),
+    'argument' => array(
+      'id' => 'numeric',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+  );
+
+  $data['language']['locked'] = array(
+    'title' => t('Locked'),
+    'help' => t('A boolean indicating whether the administrator can edit or delete the language.'),
+    'field' => array(
+      'id' => 'boolean',
+    ),
+    'filter' => array(
+      'id' => 'boolean',
+    ),
+    'argument' => array(
+      'id' => 'numeric',
+    ),
+    'sort' => array(
+      'id' => 'standard',
+    ),
+  );
+
+  return $data;
+}
diff --git a/core/modules/language/lib/Drupal/language/Plugin/views/argument/LanguageArgument.php b/core/modules/language/lib/Drupal/language/Plugin/views/argument/LanguageArgument.php
new file mode 100644
index 0000000000000000000000000000000000000000..33a461ec1a937b63cf01ef7831b67b36e600b96d
--- /dev/null
+++ b/core/modules/language/lib/Drupal/language/Plugin/views/argument/LanguageArgument.php
@@ -0,0 +1,59 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\language\Plugin\views\argument\LanguageArgument.
+ */
+
+namespace Drupal\language\Plugin\views\argument;
+
+use Drupal\views\Plugin\views\argument\ArgumentPluginBase;
+use Drupal\Core\Annotation\Plugin;
+
+/**
+ * Defines an argument handler to accept a language.
+ *
+ * @ingroup views_argument_handlers
+ *
+ * @Plugin(
+ *   id = "language",
+ *   module = "language"
+ * )
+ */
+class LanguageArgument extends ArgumentPluginBase {
+
+  /**
+   * Overrides \Drupal\views\Plugin\views\argument\ArgumentPluginBase::summary_name().
+   *
+   * Gets the user-friendly version of the language name.
+   */
+  function summary_name($data) {
+    return $this->language($data->{$this->name_alias});
+  }
+
+  /**
+   * Overrides \Drupal\views\Plugin\views\argument\ArgumentPluginBase::summary_name().
+   *
+   * Gets the user friendly version of the language name for display as a
+   * title placeholder.
+   */
+  function title() {
+    return $this->language($this->argument);
+  }
+
+  /**
+   * Returns the language name for a given langcode.
+   *
+   * @param string $langcode
+   *   The language code.
+   *
+   * @return string
+   *   The translated name for the language, or "Unknown language" if the
+   *   language was not found.
+   */
+  function language($langcode) {
+    $languages = views_language_list();
+    return isset($languages[$langcode]) ? $languages[$langcode] : t('Unknown language');
+  }
+
+}
diff --git a/core/modules/language/lib/Drupal/language/Plugin/views/field/LanguageField.php b/core/modules/language/lib/Drupal/language/Plugin/views/field/LanguageField.php
new file mode 100644
index 0000000000000000000000000000000000000000..54725f0ae64c1b0a371229c926691d23a79af253
--- /dev/null
+++ b/core/modules/language/lib/Drupal/language/Plugin/views/field/LanguageField.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\language\Plugin\views\field\LanguageField.
+ */
+
+namespace Drupal\language\Plugin\views\field;
+
+use Drupal\views\Plugin\views\field\FieldPluginBase;
+use Drupal\Core\Annotation\Plugin;
+
+/**
+ * Defines a field handler to translate a language into its readable form.
+ *
+ * @ingroup views_field_handlers
+ *
+ * @Plugin(
+ *   id = "language",
+ *   module = "language"
+ * )
+ */
+class LanguageField extends FieldPluginBase {
+
+  protected function defineOptions() {
+    $options = parent::defineOptions();
+    $options['native_language'] = array('default' => FALSE, 'bool' => TRUE);
+
+    return $options;
+  }
+
+  public function buildOptionsForm(&$form, &$form_state) {
+    parent::buildOptionsForm($form, $form_state);
+    $form['native_language'] = array(
+      '#title' => t('Native language'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->options['native_language'],
+      '#description' => t('If enabled, the native name of the language will be displayed'),
+    );
+  }
+
+  function render($values) {
+    // @todo: Drupal Core dropped native language until config translation is
+    // ready, see http://drupal.org/node/1616594.
+    $value = $this->get_value($values);
+    $language = language_load($value);
+    return $language ? $language->name : '';
+  }
+
+}
diff --git a/core/modules/language/lib/Drupal/language/Plugin/views/filter/LanguageFilter.php b/core/modules/language/lib/Drupal/language/Plugin/views/filter/LanguageFilter.php
new file mode 100644
index 0000000000000000000000000000000000000000..59a6764443c6e38d36c5f105f001276488127090
--- /dev/null
+++ b/core/modules/language/lib/Drupal/language/Plugin/views/filter/LanguageFilter.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\language\Plugin\views\filter\LanguageFilter.
+ */
+
+namespace Drupal\language\Plugin\views\filter;
+
+use Drupal\views\Plugin\views\filter\InOperator;
+use Drupal\Core\Annotation\Plugin;
+
+/**
+ * Provides filtering by language.
+ *
+ * @ingroup views_filter_handlers
+ *
+ * @Plugin(
+ *   id = "language",
+ *   module = "language"
+ * )
+ */
+class LanguageFilter extends InOperator {
+
+  function get_value_options() {
+    if (!isset($this->value_options)) {
+      $this->value_title = t('Language');
+      $languages = array(
+        '***CURRENT_LANGUAGE***' => t("Current user's language"),
+        '***DEFAULT_LANGUAGE***' => t("Default site language"),
+      );
+      $languages = array_merge($languages, views_language_list());
+      $this->value_options = $languages;
+    }
+  }
+
+}
diff --git a/core/modules/views/lib/Drupal/views/Tests/Language/ArgumentLanguageTest.php b/core/modules/views/lib/Drupal/views/Tests/Language/ArgumentLanguageTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..13cb149687e5eed1af31a5131a3a81a2e302cd42
--- /dev/null
+++ b/core/modules/views/lib/Drupal/views/Tests/Language/ArgumentLanguageTest.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\views\Tests\Language\ArgumentLanguageTest.
+ */
+
+namespace Drupal\views\Tests\Language;
+
+use Drupal\Core\Language\Language;
+
+/**
+ * Tests the argument language handler.
+ *
+ * @see Drupal\language\Plugin\views\argument\Language.php
+ */
+class ArgumentLanguageTest extends LanguageTestBase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Argument: Language',
+      'description' => 'Tests the argument language handler.',
+      'group' => 'Views Handlers'
+    );
+  }
+
+  /**
+   * Tests the language argument.
+   */
+  public function testArgument() {
+    foreach (array('en' => 'John', 'xx-lolspeak' => 'George') as $langcode => $name) {
+      $view = $this->getView();
+      $view->displayHandlers['default']->overrideOption('arguments', array(
+        'langcode' => array(
+          'id' => 'langcode',
+          'table' => 'views_test_data',
+          'field' => 'langcode',
+        ),
+      ));
+      $this->executeView($view, array($langcode));
+
+      $expected = array(array(
+        'name' => $name,
+      ));
+      $this->assertIdenticalResultset($view, $expected, array('views_test_data_name' => 'name'));
+      $view->destroy();
+    }
+  }
+
+}
diff --git a/core/modules/views/lib/Drupal/views/Tests/Language/FieldLanguageTest.php b/core/modules/views/lib/Drupal/views/Tests/Language/FieldLanguageTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0fbe8d4c08e05c31528093add6c562361bd31941
--- /dev/null
+++ b/core/modules/views/lib/Drupal/views/Tests/Language/FieldLanguageTest.php
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\views\Tests\Language\FieldLanguageTest.
+ */
+
+namespace Drupal\views\Tests\Language;
+
+use Drupal\Core\Language\Language;
+
+/**
+ * Tests the field language handler.
+ *
+ * @see Drupal\language\Plugin\views\field\Language
+ */
+class FieldLanguageTest extends LanguageTestBase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Field: Language',
+      'description' => 'Tests the field language handler.',
+      'group' => 'Views Handlers',
+    );
+  }
+
+  /**
+   * Tests the language field.
+   */
+  public function testField() {
+    $view = $this->getView();
+    $view->displayHandlers['default']->overrideOption('fields', array(
+      'langcode' => array(
+        'id' => 'langcode',
+        'table' => 'views_test_data',
+        'field' => 'langcode',
+      ),
+    ));
+    $this->executeView($view);
+
+    $this->assertEqual($view->field['langcode']->advanced_render($view->result[0]), 'English');
+    $this->assertEqual($view->field['langcode']->advanced_render($view->result[1]), 'Lolspeak');
+  }
+
+}
diff --git a/core/modules/views/lib/Drupal/views/Tests/Language/FilterLanguageTest.php b/core/modules/views/lib/Drupal/views/Tests/Language/FilterLanguageTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a2c99cc03aafe44c3ddd63199260fa827aa0ad31
--- /dev/null
+++ b/core/modules/views/lib/Drupal/views/Tests/Language/FilterLanguageTest.php
@@ -0,0 +1,51 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\views\Tests\Language\FilterLanguageTest.
+ */
+
+namespace Drupal\views\Tests\Language;
+
+use Drupal\Core\Language\Language;
+
+/**
+ * Tests the filter language handler.
+ *
+ * @see Drupal\language\Plugin\views\filter\Language
+ */
+class FilterLanguageTest extends LanguageTestBase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Filter: Language',
+      'description' => 'Tests the filter language handler.',
+      'group' => 'Views Handlers'
+    );
+  }
+
+  /**
+   * Tests the language filter.
+   */
+  public function testFilter() {
+    foreach (array('en' => 'John', 'xx-lolspeak' => 'George') as $langcode => $name) {
+      $view = $this->getView();
+      $view->displayHandlers['default']->overrideOption('filters', array(
+        'langcode' => array(
+          'id' => 'langcode',
+          'table' => 'views_test_data',
+          'field' => 'langcode',
+          'value' => array($langcode),
+        ),
+      ));
+      $this->executeView($view);
+
+      $expected = array(array(
+        'name' => $name,
+      ));
+      $this->assertIdenticalResultset($view, $expected, array('views_test_data_name' => 'name'));
+      $view->destroy();
+    }
+  }
+
+}
diff --git a/core/modules/views/lib/Drupal/views/Tests/Language/LanguageTestBase.php b/core/modules/views/lib/Drupal/views/Tests/Language/LanguageTestBase.php
new file mode 100644
index 0000000000000000000000000000000000000000..94d5a29d7945fb28dc11afc8809e6c73283b3cbe
--- /dev/null
+++ b/core/modules/views/lib/Drupal/views/Tests/Language/LanguageTestBase.php
@@ -0,0 +1,86 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\views\Tests\Language\LanguageTestBase.
+ */
+
+namespace Drupal\views\Tests\Language;
+
+use Drupal\views\Tests\ViewTestBase;
+use Drupal\Core\Language\Language;
+
+/**
+ * Defines the base class for all Language handler tests.
+ */
+abstract class LanguageTestBase extends ViewTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('language');
+
+  protected function setUp() {
+    parent::setUp();
+
+    $this->enableViewsTestModule();
+
+    // Create another language beside English.
+    $language = new Language(array('langcode' => 'xx-lolspeak', 'name' => 'Lolspeak'));
+    language_save($language);
+  }
+
+  /**
+   * Overrides \Drupal\views\Tests\ViewTestBase::schemaDefinition().
+   */
+  protected function schemaDefinition() {
+    $schema = parent::schemaDefinition();
+    $schema['views_test_data']['fields']['langcode'] = array(
+      'description' => 'The {language}.langcode of this beatle.',
+      'type' => 'varchar',
+      'length' => 12,
+      'default' => '',
+    );
+
+    return $schema;
+  }
+
+  /**
+   * Overrides \Drupal\views\Tests\ViewTestBase::schemaDefinition().
+   */
+  protected function viewsData() {
+    $data = parent::viewsData();
+    $data['views_test_data']['langcode'] = array(
+      'title' => t('Langcode'),
+      'help' => t('Langcode'),
+      'field' => array(
+        'id' => 'language',
+      ),
+      'argument' => array(
+        'id' => 'language',
+      ),
+      'filter' => array(
+        'id' => 'language',
+      ),
+    );
+
+    return $data;
+  }
+
+  /**
+   * Overrides \Drupal\views\Tests\ViewTestBase::dataSet().
+   */
+  protected function dataSet() {
+    $data = parent::dataSet();
+    $data[0]['langcode'] = 'en';
+    $data[1]['langcode'] = 'xx-lolspeak';
+    $data[2]['langcode'] = '';
+    $data[3]['langcode'] = '';
+    $data[4]['langcode'] = '';
+
+    return $data;
+  }
+
+}
diff --git a/core/modules/views/views.module b/core/modules/views/views.module
index cf10c1baa5a7d22091002527a3d3147a46c11b36..72068d134a330758ac451193f3b43382bbfe9110 100644
--- a/core/modules/views/views.module
+++ b/core/modules/views/views.module
@@ -900,26 +900,24 @@ function views_add_contextual_links(&$render_element, $location, ViewExecutable
 }
 
 /**
- * Returns an array of language names.
+ * Prepares a list of language names.
  *
- * This is a one to one copy of locale_language_list because we can't rely on enabled locale module.
+ * This is a wrapper around language_list to return a plain key value array.
  *
- * @param $field
- *   'name' => names in current language, localized
- *   'native' => native names
- * @param $all
- *   Boolean to return all languages or only enabled ones
+ * @param string $field
+ *   The field of the language object which should be used as the value of the
+ *   array.
+ * @param int $flags
+ *   (optional) Specifies the state of the languages that have to be returned.
+ *   It can be: LANGUAGE_CONFIGURABLE, LANGUAGE_LOCKED, LANGUAGE_ALL.
+ *
+ * @return array
+ *   An array of language names (or $field) keyed by the langcode.
  *
  * @see locale_language_list()
- * @todo Figure out whether we need this with language module.
  */
-function views_language_list($field = 'name', $all = FALSE) {
-  if ($all) {
-    $languages = language_list();
-  }
-  else {
-    $languages = language_list();
-  }
+function views_language_list($field = 'name', $flags = LANGUAGE_ALL) {
+  $languages = language_list($flags);
   $list = array();
   foreach ($languages as $language) {
     $list[$language->langcode] = ($field == 'name') ? t($language->name) : $language->$field;