diff --git a/core/modules/node/config/views.view.content.yml b/core/modules/node/config/views.view.content.yml
new file mode 100644
index 0000000..c15753e
--- /dev/null
+++ b/core/modules/node/config/views.view.content.yml
@@ -0,0 +1,384 @@
+base_field: nid
+base_table: node
+core: 8.x
+description: 'Find and manage content.'
+status: '1'
+display:
+  default:
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'access content overview'
+      cache:
+        type: none
+      query:
+        type: views_query
+      exposed_form:
+        type: basic
+      pager:
+        type: full
+        options:
+          items_per_page: '50'
+      style:
+        type: table
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: '1'
+          row_class_special: '1'
+          override: '1'
+          sticky: '1'
+          summary: ''
+          columns:
+            node_bulk_form: node_bulk_form
+            title: title
+            type: type
+            name: name
+            status: status
+            changed: changed
+            edit_node: edit_node
+            delete_node: delete_node
+            translation_link: translation_link
+            dropbutton: dropbutton
+          info:
+            node_bulk_form:
+              sortable: '0'
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: '0'
+              responsive: ''
+            title:
+              sortable: '1'
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: '0'
+              responsive: ''
+            type:
+              sortable: '1'
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: '0'
+              responsive: priority-medium
+            name:
+              sortable: '0'
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: '0'
+              responsive: priority-low
+            status:
+              sortable: '1'
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: '0'
+              responsive: ''
+            changed:
+              sortable: '1'
+              default_sort_order: desc
+              align: ''
+              separator: ''
+              empty_column: '0'
+              responsive: priority-low
+            edit_node:
+              sortable: '0'
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: '0'
+              responsive: ''
+            delete_node:
+              sortable: '0'
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: '0'
+              responsive: ''
+            translation_link:
+              align: ''
+              separator: ''
+              empty_column: '0'
+              responsive: ''
+            dropbutton:
+              sortable: '0'
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: '0'
+              responsive: ''
+          default: changed
+          empty_table: '1'
+      row:
+        type: fields
+      fields:
+        node_bulk_form:
+          id: node_bulk_form
+          table: node
+          field: node_bulk_form
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: '0'
+          alter:
+            alter_text: '0'
+          element_class: ''
+          element_default_classes: '1'
+          empty: ''
+          hide_empty: '0'
+          empty_zero: '0'
+          hide_alter_empty: '1'
+          plugin_id: node_bulk_form
+        title:
+          id: title
+          table: node
+          field: title
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Title
+          exclude: '0'
+          alter:
+            alter_text: '0'
+          element_class: ''
+          element_default_classes: '1'
+          empty: ''
+          hide_empty: '0'
+          empty_zero: '0'
+          hide_alter_empty: '1'
+          link_to_node: '1'
+          plugin_id: node
+        type:
+          id: type
+          table: node
+          field: type
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Content Type'
+          exclude: '0'
+          alter:
+            alter_text: '0'
+          element_class: ''
+          element_default_classes: '1'
+          empty: ''
+          hide_empty: '0'
+          empty_zero: '0'
+          hide_alter_empty: '1'
+          link_to_node: '0'
+          machine_name: '0'
+          plugin_id: node_type
+        name:
+          id: name
+          table: users
+          field: name
+          relationship: uid
+          group_type: group
+          admin_label: ''
+          label: Author
+          exclude: '0'
+          alter:
+            alter_text: '0'
+          element_class: ''
+          element_default_classes: '1'
+          empty: ''
+          hide_empty: '0'
+          empty_zero: '0'
+          hide_alter_empty: '1'
+          link_to_user: '1'
+          overwrite_anonymous: '0'
+          anonymous_text: ''
+          format_username: '1'
+          plugin_id: user_name
+        status:
+          id: status
+          table: node
+          field: status
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Status
+          exclude: '0'
+          alter:
+            alter_text: '0'
+          element_class: ''
+          element_default_classes: '1'
+          empty: ''
+          hide_empty: '0'
+          empty_zero: '0'
+          hide_alter_empty: '1'
+          type: published-notpublished
+          type_custom_true: ''
+          type_custom_false: ''
+          not: '0'
+          plugin_id: boolean
+        changed:
+          id: changed
+          table: node
+          field: changed
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Updated
+          exclude: '0'
+          alter:
+            alter_text: '0'
+          element_class: ''
+          element_default_classes: '1'
+          empty: ''
+          hide_empty: '0'
+          empty_zero: '0'
+          hide_alter_empty: '1'
+          date_format: short
+          custom_date_format: ''
+          timezone: ''
+          plugin_id: date
+        edit_node:
+          id: edit_node
+          table: views_entity_node
+          field: edit_node
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: '1'
+          text: Edit
+          plugin_id: node_link_edit
+        delete_node:
+          id: delete_node
+          table: views_entity_node
+          field: delete_node
+          label: ''
+          exclude: '1'
+          text: Delete
+          plugin_id: node_link_delete
+        translation_link:
+          id: translation_link
+          table: node
+          field: translation_link
+          label: ''
+          exclude: '1'
+          alter:
+            alter_text: '0'
+          element_class: ''
+          element_default_classes: '1'
+          hide_alter_empty: '1'
+          hide_empty: '0'
+          empty_zero: '0'
+          empty: ''
+          text: Translate
+          optional: '1'
+          plugin_id: translation_entity_link
+        dropbutton:
+          id: dropbutton
+          table: views
+          field: dropbutton
+          label: Operations
+          fields:
+            edit_node: edit_node
+            delete_node: delete_node
+            translation_link: translation_link
+          destination: '1'
+          plugin_id: dropbutton
+      filters:
+        status_extra:
+          id: status_extra
+          table: node
+          field: status_extra
+          operator: '='
+          value: ''
+          plugin_id: node_status
+        status:
+          id: status
+          table: node
+          field: status
+          operator: '='
+          value: All
+          exposed: '1'
+          expose:
+            operator_id: ''
+            label: Status
+            description: ''
+            use_operator: '0'
+            operator: status_op
+            identifier: status
+            required: '0'
+            remember: '0'
+            multiple: '0'
+            remember_roles:
+              authenticated: authenticated
+          plugin_id: boolean
+        type:
+          id: type
+          table: node
+          field: type
+          operator: in
+          value: {  }
+          exposed: '1'
+          expose:
+            operator_id: type_op
+            label: Type
+            description: ''
+            use_operator: '0'
+            operator: type_op
+            identifier: type
+            required: '0'
+            remember: '0'
+            multiple: '0'
+            remember_roles:
+              authenticated: authenticated
+            reduce: '0'
+          plugin_id: bundle
+      sorts: {  }
+      title: Content
+      empty:
+        area_text_custom:
+          id: area_text_custom
+          table: views
+          field: area_text_custom
+          empty: '1'
+          content: 'No content available.'
+          plugin_id: text_custom
+      arguments: {  }
+      relationships:
+        uid:
+          id: uid
+          table: node
+          field: uid
+          admin_label: author
+          required: '1'
+          plugin_id: standard
+      show_admin_links: '0'
+    display_plugin: default
+    display_title: Master
+    id: default
+    position: '0'
+  page_1:
+    display_options:
+      path: admin/content/node
+      menu:
+        type: 'default tab'
+        title: Content
+        description: ''
+        name: admin
+        weight: '-10'
+        context: '0'
+      tab_options:
+        type: normal
+        title: Content
+        description: 'Find and manage content'
+        name: admin
+        weight: '0'
+    display_plugin: page
+    display_title: Page
+    id: page_1
+    position: '1'
+label: Content
+module: views
+id: content
+tag: 'default'
+langcode: en
diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/field/NodeBulkForm.php b/core/modules/node/lib/Drupal/node/Plugin/views/field/NodeBulkForm.php
new file mode 100644
index 0000000..6a3dc4f
--- /dev/null
+++ b/core/modules/node/lib/Drupal/node/Plugin/views/field/NodeBulkForm.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\node\Plugin\views\field\NodeBulkForm.
+ */
+
+namespace Drupal\node\Plugin\views\field;
+
+use Drupal\Component\Annotation\PluginID;
+use Drupal\system\Plugin\views\field\BulkFormBase;
+
+/**
+ * Defines a node operations bulk form element.
+ *
+ * @PluginID("node_bulk_form")
+ */
+class NodeBulkForm extends BulkFormBase {
+
+  /**
+   * Implements \Drupal\system\Plugin\views\field\BulkFormBase::getBulkOptions().
+   */
+  protected function getBulkOptions() {
+    module_load_include('inc', 'node', 'node.admin');
+    return array_map(function($operation) {
+      return $operation['label'];
+    }, module_invoke_all('node_operations'));
+  }
+
+  /**
+   * Implements \Drupal\system\Plugin\views\field\BulkFormBase::views_form_submit().
+   */
+  public function views_form_submit(&$form, &$form_state) {
+    if ($form_state['step'] == 'views_form_views_form') {
+      // Filter only selected checkboxes.
+      $selected = array_filter($form_state['values'][$this->options['id']]);
+      $nodes = array();
+      foreach (array_intersect_key($this->view->result, $selected) as $node) {
+        $nid = $this->get_entity($node)->id();
+        $nodes[$nid] = $nid;
+      }
+
+      $submit = array(
+        'values' => array(
+          'operation' => $form_state['values']['action'],
+          'nodes' => $nodes,
+        ),
+      );
+      // @todo Move the submit function code here.
+      module_load_include('inc', 'node', 'node.admin');
+      node_admin_nodes_submit($form, $submit);
+    }
+  }
+
+}
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeAdminTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeAdminTest.php
index bcfbfcd..e1d30c0 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeAdminTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeAdminTest.php
@@ -12,6 +12,8 @@
  */
 class NodeAdminTest extends NodeTestBase {
 
+  public static $modules = array('views');
+
   public static function getInfo() {
     return array(
       'name' => 'Node administration',
@@ -95,15 +97,13 @@ function testContentAdminPages() {
       $this->assertLinkByHref('node/' . $node->nid);
       $this->assertLinkByHref('node/' . $node->nid . '/edit');
       $this->assertLinkByHref('node/' . $node->nid . '/delete');
-      // Verify tableselect.
-      $this->assertFieldByName('nodes[' . $node->nid . ']', '', 'Tableselect found.');
     }
 
     // Verify filtering by publishing status.
     $edit = array(
-      'status' => 'status-1',
+      'status' => '1',
     );
-    $this->drupalPost(NULL, $edit, t('Filter'));
+    $this->drupalPost(NULL, $edit, t('Apply'));
 
     $this->assertRaw(t('where %property is %value', array('%property' => t('status'), '%value' => 'published')), 'Content list is filtered by status.');
 
@@ -112,10 +112,10 @@ function testContentAdminPages() {
     $this->assertNoLinkByHref('node/' . $nodes['unpublished_page_1']->nid . '/edit');
 
     // Verify filtering by status and content type.
-    $edit = array(
+    $edit += array(
       'type' => 'page',
     );
-    $this->drupalPost(NULL, $edit, t('Refine'));
+    $this->drupalPost(NULL, $edit, t('Apply'));
 
     $this->assertRaw(t('where %property is %value', array('%property' => t('status'), '%value' => 'published')), 'Content list is filtered by status.');
     $this->assertRaw(t('and where %property is %value', array('%property' => t('type'), '%value' => 'Basic page')), 'Content list is filtered by content type.');
diff --git a/core/modules/node/lib/Drupal/node/Tests/Views/BulkFormTest.php b/core/modules/node/lib/Drupal/node/Tests/Views/BulkFormTest.php
new file mode 100644
index 0000000..128cb4f
--- /dev/null
+++ b/core/modules/node/lib/Drupal/node/Tests/Views/BulkFormTest.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\node\Tests\Views\BulkFormTest.
+ */
+
+namespace Drupal\node\Tests\Views;
+
+/**
+ * Tests the views bulk form test.
+ *
+ * @see \Drupal\node\Plugin\views\field\BulkForm
+ */
+class BulkFormTest extends NodeTestBase {
+
+  /**
+   * Views used by this test.
+   *
+   * @var array
+   */
+  public static $testViews = array('test_node_bulk_form');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Node: Bulk form',
+      'description' => 'Tests a node bulk form.',
+      'group' => 'Views Modules',
+    );
+  }
+
+  /**
+   * Tests the node bulk form.
+   */
+  public function testBulkForm() {
+    $this->drupalLogin($this->drupalCreateUser(array('administer nodes')));
+    $node = $this->drupalCreateNode();
+
+    $this->drupalGet('test-node-bulk-form');
+    $elements = $this->xpath('//select[@id="edit-action"]//option');
+    $this->assertIdentical(count($elements), 7, 'All node operations are found.');
+
+    // Block a node using the bulk form.
+    $this->assertTrue($node->status);
+    $edit = array(
+      'node_bulk_form[0]' => TRUE,
+      'action' => 'unpublish',
+    );
+    $this->drupalPost(NULL, $edit, t('Apply'));
+    // Re-load the node and check their status.
+    $node = entity_load('node', $node->id());
+    $this->assertFalse($node->status);
+  }
+
+}
diff --git a/core/modules/node/node.admin.inc b/core/modules/node/node.admin.inc
index 139b2d2..3889335 100644
--- a/core/modules/node/node.admin.inc
+++ b/core/modules/node/node.admin.inc
@@ -74,197 +74,6 @@ function node_node_operations() {
 }
 
 /**
- * Lists node administration filters that can be applied.
- *
- * @return
- *   An associative array of filters.
- */
-function node_filters() {
-  // Regular filters
-  $filters['status'] = array(
-    'title' => t('status'),
-    'options' => array(
-      '[any]' => t('any'),
-      'status-1' => t('published'),
-      'status-0' => t('not published'),
-      'promote-1' => t('promoted'),
-      'promote-0' => t('not promoted'),
-      'sticky-1' => t('sticky'),
-      'sticky-0' => t('not sticky'),
-    ),
-  );
-  // Include translation states if we have this module enabled
-  if (module_exists('translation')) {
-    $filters['status']['options'] += array(
-      'translate-0' => t('Up to date translation'),
-      'translate-1' => t('Outdated translation'),
-    );
-  }
-
-  $filters['type'] = array(
-    'title' => t('type'),
-    'options' => array(
-      '[any]' => t('any'),
-    ) + node_type_get_names(),
-  );
-
-  // Language filter if language support is present.
-  if (language_multilingual()) {
-    $languages = language_list(LANGUAGE_ALL);
-    foreach ($languages as $langcode => $language) {
-      // Make locked languages appear special in the list.
-      $language_options[$langcode] = $language->locked ? t('- @name -', array('@name' => $language->name)) : $language->name;
-    }
-    $filters['langcode'] = array(
-      'title' => t('language'),
-      'options' => array(
-        '[any]' => t('- Any -'),
-      ) + $language_options,
-    );
-  }
-  return $filters;
-}
-
-/**
- * Applies filters for the node administration overview based on session.
- *
- * @param Drupal\Core\Database\Query\SelectInterface $query
- *   A SelectQuery to which the filters should be applied.
- */
-function node_build_filter_query(SelectInterface $query) {
-  // Build query
-  $filter_data = isset($_SESSION['node_overview_filter']) ? $_SESSION['node_overview_filter'] : array();
-  foreach ($filter_data as $index => $filter) {
-    list($key, $value) = $filter;
-    switch ($key) {
-      case 'status':
-        // Note: no exploitable hole as $key/$value have already been checked when submitted
-        list($key, $value) = explode('-', $value, 2);
-      case 'type':
-      case 'langcode':
-        $query->condition('n.' . $key, $value);
-        break;
-    }
-  }
-}
-
-/**
- * Returns the node administration filters form array to node_admin_content().
- *
- * @see node_admin_nodes()
- * @see node_admin_nodes_submit()
- * @see node_admin_nodes_validate()
- * @see node_filter_form_submit()
- * @see node_multiple_delete_confirm()
- * @see node_multiple_delete_confirm_submit()
- *
- * @ingroup forms
- */
-function node_filter_form() {
-  $session = isset($_SESSION['node_overview_filter']) ? $_SESSION['node_overview_filter'] : array();
-  $filters = node_filters();
-
-  $i = 0;
-  $form['filters'] = array(
-    '#type' => 'details',
-    '#title' => t('Show only items where'),
-    '#theme' => 'exposed_filters__node',
-  );
-  foreach ($session as $filter) {
-    list($type, $value) = $filter;
-    if ($type == 'term') {
-      // Load term name from DB rather than search and parse options array.
-      $value = module_invoke('taxonomy', 'term_load', $value);
-      $value = $value->name;
-    }
-    elseif ($type == 'langcode') {
-      $value = language_name($value);
-    }
-    else {
-      $value = $filters[$type]['options'][$value];
-    }
-    $t_args = array('%property' => $filters[$type]['title'], '%value' => $value);
-    if ($i++) {
-      $form['filters']['current'][] = array('#markup' => t('and where %property is %value', $t_args));
-    }
-    else {
-      $form['filters']['current'][] = array('#markup' => t('where %property is %value', $t_args));
-    }
-    if (in_array($type, array('type', 'langcode'))) {
-      // Remove the option if it is already being filtered on.
-      unset($filters[$type]);
-    }
-  }
-
-  $form['filters']['status'] = array(
-    '#type' => 'container',
-    '#attributes' => array('class' => array('clearfix')),
-    '#prefix' => ($i ? '<div class="additional-filters">' . t('and where') . '</div>' : ''),
-  );
-  $form['filters']['status']['filters'] = array(
-    '#type' => 'container',
-    '#attributes' => array('class' => array('filters')),
-  );
-  foreach ($filters as $key => $filter) {
-    $form['filters']['status']['filters'][$key] = array(
-      '#type' => 'select',
-      '#options' => $filter['options'],
-      '#title' => $filter['title'],
-      '#default_value' => '[any]',
-    );
-  }
-
-  $form['filters']['status']['actions'] = array(
-    '#type' => 'actions',
-    '#attributes' => array('class' => array('container-inline')),
-  );
-  $form['filters']['status']['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => count($session) ? t('Refine') : t('Filter'),
-  );
-  if (count($session)) {
-    $form['filters']['status']['actions']['undo'] = array('#type' => 'submit', '#value' => t('Undo'));
-    $form['filters']['status']['actions']['reset'] = array('#type' => 'submit', '#value' => t('Reset'));
-  }
-
-  $form['#attached']['library'][] = array('system', 'drupal.form');
-
-  return $form;
-}
-
-/**
- * Form submission handler for node_filter_form().
- *
- * @see node_admin_content()
- * @see node_admin_nodes()
- * @see node_admin_nodes_submit()
- * @see node_admin_nodes_validate()
- * @see node_filter_form()
- * @see node_multiple_delete_confirm()
- * @see node_multiple_delete_confirm_submit()
- */
-function node_filter_form_submit($form, &$form_state) {
-  $filters = node_filters();
-  switch ($form_state['values']['op']) {
-    case t('Filter'):
-    case t('Refine'):
-      // Apply every filter that has a choice selected other than 'any'.
-      foreach ($filters as $filter => $options) {
-        if (isset($form_state['values'][$filter]) && $form_state['values'][$filter] != '[any]') {
-          $_SESSION['node_overview_filter'][] = array($filter, $form_state['values'][$filter]);
-        }
-      }
-      break;
-    case t('Undo'):
-      array_pop($_SESSION['node_overview_filter']);
-      break;
-    case t('Reset'):
-      $_SESSION['node_overview_filter'] = array();
-      break;
-  }
-}
-
-/**
  * Updates all nodes in the passed-in array with the passed-in field values.
  *
  * IMPORTANT NOTE: This function is intended to work when called from a form
@@ -391,30 +200,6 @@ function _node_mass_update_batch_finished($success, $results, $operations) {
 }
 
 /**
- * Page callback: Form constructor for the content administration form.
- *
- * @see node_admin_nodes()
- * @see node_admin_nodes_submit()
- * @see node_admin_nodes_validate()
- * @see node_filter_form()
- * @see node_filter_form_submit()
- * @see node_menu()
- * @see node_multiple_delete_confirm()
- * @see node_multiple_delete_confirm_submit()
- * @ingroup forms
- */
-function node_admin_content($form, $form_state) {
-  if (isset($form_state['values']['operation']) && $form_state['values']['operation'] == 'delete') {
-    return node_multiple_delete_confirm($form, $form_state, array_filter($form_state['values']['nodes']));
-  }
-  $form['filter'] = node_filter_form();
-  $form['#submit'][] = 'node_filter_form_submit';
-  $form['admin'] = node_admin_nodes();
-
-  return $form;
-}
-
-/**
  * Returns the admin form object to node_admin_content().
  *
  * @see node_admin_nodes_submit()
@@ -426,33 +211,6 @@ function node_admin_content($form, $form_state) {
  * @ingroup forms
  */
 function node_admin_nodes() {
-  $admin_access = user_access('administer nodes');
-
-  // Build the 'Update options' form.
-  $form['options'] = array(
-    '#type' => 'details',
-    '#title' => t('Update options'),
-    '#attributes' => array('class' => array('container-inline')),
-    '#access' => $admin_access,
-  );
-  $options = array();
-  foreach (module_invoke_all('node_operations') as $operation => $array) {
-    $options[$operation] = $array['label'];
-  }
-  $form['options']['operation'] = array(
-    '#type' => 'select',
-    '#title' => t('Operation'),
-    '#title_display' => 'invisible',
-    '#options' => $options,
-    '#default_value' => 'approve',
-  );
-  $form['options']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Update'),
-    '#tableselect' => TRUE,
-    '#submit' => array('node_admin_nodes_submit'),
-  );
-
   // Enable language column and filter if multiple languages are enabled.
   $multilingual = language_multilingual();
 
@@ -490,7 +248,6 @@ function node_admin_nodes() {
   $query = db_select('node', 'n')
     ->extend('Drupal\Core\Database\Query\PagerSelectExtender')
     ->extend('Drupal\Core\Database\Query\TableSortExtender');
-  node_build_filter_query($query);
 
   if (!user_access('bypass node access')) {
     // If the user is able to view their own unpublished nodes, allow them
@@ -519,35 +276,35 @@ function node_admin_nodes() {
   // Prepare the list of nodes.
   $languages = language_list(LANGUAGE_ALL);
   $destination = drupal_get_destination();
-  $form['nodes'] = array(
+  $build['nodes'] = array(
     '#type' => 'table',
     '#header' => $header,
     '#empty' => t('No content available.'),
   );
   foreach ($nodes as $node) {
     $l_options = $node->langcode != LANGUAGE_NOT_SPECIFIED && isset($languages[$node->langcode]) ? array('language' => $languages[$node->langcode]) : array();
-    $form['nodes'][$node->nid]['title'] = array(
+    $build['nodes'][$node->nid]['title'] = array(
       '#type' => 'link',
       '#title' => $node->label(),
       '#href' => 'node/' . $node->nid,
       '#options' => $l_options,
       '#suffix' => ' ' . theme('mark', array('type' => node_mark($node->nid, $node->changed))),
     );
-    $form['nodes'][$node->nid]['type'] = array(
+    $build['nodes'][$node->nid]['type'] = array(
       '#markup' => check_plain(node_get_type_label($node)),
     );
-    $form['nodes'][$node->nid]['author'] = array(
+    $build['nodes'][$node->nid]['author'] = array(
       '#theme' => 'username',
       '#account' => $node,
     );
-    $form['nodes'][$node->nid]['status'] = array(
+    $build['nodes'][$node->nid]['status'] = array(
       '#markup' => $node->status ? t('published') : t('not published'),
     );
-    $form['nodes'][$node->nid]['changed'] = array(
+    $build['nodes'][$node->nid]['changed'] = array(
       '#markup' => format_date($node->changed, 'short'),
     );
     if ($multilingual) {
-      $form['nodes'][$node->nid]['language_name'] = array(
+      $build['nodes'][$node->nid]['language_name'] = array(
         '#markup' => language_name($node->langcode),
       );
     }
@@ -575,10 +332,10 @@ function node_admin_nodes() {
         'query' => $destination,
       );
     }
-    $form['nodes'][$node->nid]['operations'] = array();
+    $build['nodes'][$node->nid]['operations'] = array();
     if (count($operations) > 1) {
       // Render an unordered list of operations links.
-      $form['nodes'][$node->nid]['operations'] = array(
+      $build['nodes'][$node->nid]['operations'] = array(
         '#type' => 'operations',
         '#subtype' => 'node',
         '#links' => $operations,
@@ -587,7 +344,7 @@ function node_admin_nodes() {
     elseif (!empty($operations)) {
       // Render the first and only operation as a link.
       $link = reset($operations);
-      $form['nodes'][$node->nid]['operations'] = array(
+      $build['nodes'][$node->nid]['operations'] = array(
         '#type' => 'link',
         '#title' => $link['title'],
         '#href' => $link['href'],
@@ -596,14 +353,8 @@ function node_admin_nodes() {
     }
   }
 
-  // Only use a tableselect when the current user is able to perform any
-  // operations.
-  if ($admin_access) {
-    $form['nodes']['#tableselect'] = TRUE;
-  }
-
-  $form['pager'] = array('#theme' => 'pager');
-  return $form;
+  $build['pager'] = array('#theme' => 'pager');
+  return $build;
 }
 
 /**
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 8f9f17f..270a79f 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -1646,8 +1646,7 @@ function node_menu() {
   $items['admin/content'] = array(
     'title' => 'Content',
     'description' => 'Find and manage content.',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('node_admin_content'),
+    'page callback' => 'node_admin_nodes',
     'access arguments' => array('access content overview'),
     'weight' => -10,
     'file' => 'node.admin.inc',
diff --git a/core/modules/node/node.views.inc b/core/modules/node/node.views.inc
index 6f3320f..f344cfe 100644
--- a/core/modules/node/node.views.inc
+++ b/core/modules/node/node.views.inc
@@ -219,6 +219,14 @@ function node_views_data() {
     );
   }
 
+  $data['node']['node_bulk_form'] = array(
+    'title' => t('Node operations bulk form'),
+    'help' => t('Add a form element that lets you run operations on multiple nodes.'),
+    'field' => array(
+      'id' => 'node_bulk_form',
+    ),
+  );
+
   // Define some fields based upon views_handler_field_entity in the entity
   // table so they can be re-used with other query backends.
   // @see views_handler_field_entity
diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_bulk_form.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_bulk_form.yml
new file mode 100644
index 0000000..4be60b5
--- /dev/null
+++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_bulk_form.yml
@@ -0,0 +1,45 @@
+base_field: nid
+base_table: node
+core: 8.x
+description: ''
+disabled: '0'
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: ''
+    display_options:
+      style:
+        type: table
+      row:
+        type: fields
+      fields:
+        node_bulk_form:
+          id: node_bulk_form
+          table: node
+          field: node_bulk_form
+          plugin_id: node_bulk_form
+        title:
+          id: title
+          table: node
+          field: title
+          plugin_id: node
+      sorts:
+        nid:
+          id: nid
+          table: node
+          field: nid
+          order: ASC
+          plugin_id: standard
+  page_1:
+    display_plugin: page
+    id: page_1
+    display_title: Page
+    position: ''
+    display_options:
+      path: test-node-bulk-form
+label: ''
+module: views
+id: test_node_bulk_form
+tag: ''
