diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index 8cb009a6357ba9e78f601d0a1260a6e8d0759175..bdc89f1a89f31a67fd04bc8831d9d836558c2236 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -454,7 +454,7 @@ function entity_form_submit_build_entity($entity_type, $entity, $form, &$form_st
   // this form. Copying field values must be done using field_attach_submit().
   $values_excluding_fields = $info['fieldable'] ? array_diff_key($form_state['values'], field_info_instances($entity_type, $entity->bundle())) : $form_state['values'];
   foreach ($values_excluding_fields as $key => $value) {
-    $entity->$key = $value;
+    $entity->set($key, $value);
   }
 
   // Invoke all specified builders for copying form values to entity properties.
diff --git a/core/modules/views/lib/Drupal/views/Plugin/Core/Entity/View.php b/core/modules/views/lib/Drupal/views/Plugin/Core/Entity/View.php
index 3f39af80145b07ef2555005849eb57075ccc93df..29be1f6c4cf61e689203b058945abcabbaefed82 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/Core/Entity/View.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/Core/Entity/View.php
@@ -26,7 +26,8 @@
  *   form_controller_class = {
  *     "edit" = "Drupal\views_ui\ViewEditFormController",
  *     "add" = "Drupal\views_ui\ViewAddFormController",
- *     "preview" = "Drupal\views_ui\ViewPreviewFormController"
+ *     "preview" = "Drupal\views_ui\ViewPreviewFormController",
+ *     "clone" = "Drupal\views_ui\ViewCloneFormController"
  *   },
  *   config_prefix = "views.view",
  *   fieldable = FALSE,
diff --git a/core/modules/views/lib/Drupal/views/Tests/UI/DefaultViewsTest.php b/core/modules/views/lib/Drupal/views/Tests/UI/DefaultViewsTest.php
index 770f1bf619a46e85ea9518d7cd488a913df46774..a274311f1bfb24ffb52b7b4467e86ef8eb61a7f1 100644
--- a/core/modules/views/lib/Drupal/views/Tests/UI/DefaultViewsTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/UI/DefaultViewsTest.php
@@ -73,6 +73,23 @@ function testDefaultViews() {
     // $this->drupalGet('frontpage');
     // $this->assertNoText($new_title);
 
+    // Clone the view and check that the normal schema of cloned views is used.
+    $this->drupalGet('admin/structure/views');
+    $this->clickViewsOperationLink(t('Clone'), '/frontpage');
+    $edit = array(
+      'name' => 'clone_of_frontpage',
+    );
+    $this->assertTitle(t('Clone of @human_name | @site-name', array('@human_name' => 'Front page', '@site-name' => config('system.site')->get('name'))));
+    $this->drupalPost(NULL, $edit, t('Clone'));
+    $this->assertUrl('admin/structure/views/view/clone_of_frontpage/edit', array(), 'The normal cloning name schema is applied.');
+
+    // Clone a view and set a custom name.
+    $this->drupalGet('admin/structure/views');
+    $this->clickViewsOperationLink(t('Clone'), '/frontpage');
+    $random_name = strtolower($this->randomName());
+    $this->drupalPost(NULL, array('name' => $random_name), t('Clone'));
+    $this->assertUrl("admin/structure/views/view/$random_name/edit", array(), 'The custom view name got saved.');
+
     // Now disable the view, and make sure it stops appearing on the main view
     // listing page but instead goes back to displaying on the disabled views
     // listing page.
@@ -126,7 +143,7 @@ function clickViewsOperationLink($label, $unique_href_part) {
         break;
       }
     }
-    $this->assertTrue(isset($index), t('Link to "@label" containing @part found.', array('@label' => $label, '@part' => $unique_href_part)));
+    $this->assertTrue(isset($index), format_string('Link to "@label" containing @part found.', array('@label' => $label, '@part' => $unique_href_part)));
     if (isset($index)) {
       return $this->clickLink($label, $index);
     }
diff --git a/core/modules/views/views_ui/lib/Drupal/views_ui/ViewCloneFormController.php b/core/modules/views/views_ui/lib/Drupal/views_ui/ViewCloneFormController.php
new file mode 100644
index 0000000000000000000000000000000000000000..70f18a932ffbf3c2ba3e4ce420b1bf8f13780e44
--- /dev/null
+++ b/core/modules/views/views_ui/lib/Drupal/views_ui/ViewCloneFormController.php
@@ -0,0 +1,80 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views_ui\ViewCloneFormController.
+ */
+
+namespace Drupal\views_ui;
+
+use Drupal\Core\Entity\EntityInterface;
+
+/**
+ * Form controller for the Views clone form.
+ */
+class ViewCloneFormController extends ViewFormControllerBase {
+
+  /**
+   * Overrides \Drupal\Core\Entity\EntityFormController::prepareForm().
+   */
+  protected function prepareEntity(EntityInterface $entity) {
+    // Do not prepare the entity while it is being added.
+  }
+
+  /**
+   * Overrides \Drupal\Core\Entity\EntityFormController::form().
+   */
+  public function form(array $form, array &$form_state, EntityInterface $entity) {
+    parent::form($form, $form_state, $entity);
+
+    $form['human_name'] = array(
+      '#type' => 'textfield',
+      '#title' => t('View name'),
+      '#required' => TRUE,
+      '#size' => 32,
+      '#default_value' => '',
+      '#maxlength' => 255,
+      '#default_value' => t('Clone of @human_name', array('@human_name' => $entity->getHumanName())),
+    );
+    $form['name'] = array(
+      '#type' => 'machine_name',
+      '#maxlength' => 128,
+      '#machine_name' => array(
+        'exists' => 'views_get_view',
+        'source' => array('human_name'),
+      ),
+      '#default_value' => '',
+      '#description' => t('A unique machine-readable name for this View. It must only contain lowercase letters, numbers, and underscores.'),
+    );
+
+    return $form;
+  }
+
+  /**
+   * Overrides \Drupal\Core\Entity\EntityFormController::actions().
+   */
+  protected function actions(array $form, array &$form_state) {
+    $actions['submit'] = array(
+      '#value' => t('Clone'),
+      '#submit' => array(
+        array($this, 'submit'),
+      ),
+    );
+    return $actions;
+  }
+
+  /**
+   * Overrides \Drupal\Core\Entity\EntityFormController::form().
+   */
+  public function submit(array $form, array &$form_state) {
+    $entity = parent::submit($form, $form_state);
+    $entity->setOriginalID(NULL);
+    $entity->save();
+
+    // Redirect the user to the view admin form.
+    $uri = $entity->uri();
+    $form_state['redirect'] = $uri['path'] . '/edit';
+    return $entity;
+  }
+
+}
diff --git a/core/modules/views/views_ui/lib/Drupal/views_ui/ViewListController.php b/core/modules/views/views_ui/lib/Drupal/views_ui/ViewListController.php
index ac8dc4ea296f9125c77ad380bbff8ad0255b9413..a3e2bea4c224bf79ebdc49949ba9710d82c463b4 100644
--- a/core/modules/views/views_ui/lib/Drupal/views_ui/ViewListController.php
+++ b/core/modules/views/views_ui/lib/Drupal/views_ui/ViewListController.php
@@ -123,6 +123,12 @@ public function getOperations(EntityInterface $view) {
         'weight' => 10,
       );
     }
+    $definition['clone'] = array(
+      'title' => t('Clone'),
+      'href' => "$path/clone",
+      'weight' => 15,
+    );
+
     return $definition;
   }
 
diff --git a/core/modules/views/views_ui/views_ui.module b/core/modules/views/views_ui/views_ui.module
index feb6553b44ba8d2b43ad09ede509c62509606709..b7040acda179a3687736f08b384137ccc449f296 100644
--- a/core/modules/views/views_ui/views_ui.module
+++ b/core/modules/views/views_ui/views_ui.module
@@ -6,6 +6,7 @@
  */
 
 use Drupal\views\ViewExecutable;
+use Drupal\views\Plugin\Core\Entity\View;
 use Drupal\views_ui\ViewUI;
 use Drupal\views\Analyzer;
 use Drupal\Core\Entity\EntityInterface;
@@ -49,6 +50,14 @@ function views_ui_menu() {
     'type' => MENU_DEFAULT_LOCAL_TASK,
   ) + $base;
 
+  $items['admin/structure/views/view/%views_ui_cache/clone'] = array(
+    'title callback' => 'views_ui_clone_title',
+    'title arguments' => array(4),
+    'page callback' => 'entity_get_form',
+    'page arguments' => array(4, 'clone'),
+    'type' => MENU_CALLBACK,
+  ) + $base;
+
   $items['admin/structure/views/view/%views_ui/enable'] = array(
     'title' => 'Enable a view',
   ) + $ajax_base;
@@ -373,6 +382,16 @@ function views_ui_cache_set(ViewUI $view) {
   drupal_container()->get('user.tempstore')->get('views')->set($view->get('name'), $view);
 }
 
+/**
+ * Title callback for the views clone form.
+ *
+ * @param \Drupal\views\ViewExecutable $view
+ *   The view to clone.
+ */
+function views_ui_clone_title(ViewUI $view) {
+  return t('Clone of @human_name', array('@human_name' => $view->getHumanName()));
+}
+
 /**
  * Theme preprocess for views-view.tpl.php.
  */