diff --git a/core/modules/edit/lib/Drupal/edit/EditController.php b/core/modules/edit/lib/Drupal/edit/EditController.php
index ce1773d..e64598d 100644
--- a/core/modules/edit/lib/Drupal/edit/EditController.php
+++ b/core/modules/edit/lib/Drupal/edit/EditController.php
@@ -15,6 +15,7 @@
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityManager;
+use Drupal\Core\Entity\EntityChangedInterface;
 use Drupal\field\FieldInfo;
 use Drupal\edit\MetadataGeneratorInterface;
 use Drupal\edit\EditorSelectorInterface;
@@ -192,40 +193,60 @@ public function attachments(Request $request) {
   public function fieldForm(EntityInterface $entity, $field_name, $langcode, $view_mode_id, Request $request) {
     $response = new AjaxResponse();
 
+    if ($entity instanceof EntityChangedInterface) {
+      $entity_timestamp = $entity->getChangedTime();
+    }
+
     // Replace entity with tempstore copy if available and not resetting, init
     // tempstore copy otherwise.
     $tempstore_entity = $this->tempStoreFactory->get('edit')->get($entity->uuid());
     if ($tempstore_entity && $request->request->get('reset') !== 'true') {
+      if ($tempstore_entity instanceof EntityChangedInterface) {
+        $old_entity_timestamp = $tempstore_entity->getChangedTime();
+      }
       $entity = $tempstore_entity;
     }
     else {
       $this->tempStoreFactory->get('edit')->set($entity->uuid(), $entity);
     }
 
-    $form_state = array(
-      'langcode' => $langcode,
-      'no_redirect' => TRUE,
-      'build_info' => array('args' => array($entity, $field_name, $this->tempStoreFactory)),
-    );
-    $form = drupal_build_form('edit_field_form', $form_state);
-
-    if (!empty($form_state['executed'])) {
-      // The form submission saved the entity in tempstore. Return the
-      // updated view of the field from the tempstore copy.
-      $entity = $this->tempStoreFactory->get('edit')->get($entity->uuid());
-      $output = field_view_field($entity, $field_name, $view_mode_id, $langcode);
+    // Detect an edit conflict if the current entity timestamp is different
+    // from the tempstore entity timestamp (whch is a copy from when the
+    // editing process started).
+    if (!empty($entity_timestamp) && !empty($old_entity_timestamp) && ($entity_timestamp != $old_entity_timestamp)) {
+      drupal_set_message(t('The copy of the content being edites is outdated. Reload the page to edit an up-to-date version.'), 'error');
 
-      $response->addCommand(new FieldFormSavedCommand(drupal_render($output)));
+      $status_messages = array(
+        '#theme' => 'status_messages'
+      );
+      $response->addCommand(new FieldFormValidationErrorsCommand(drupal_render($status_messages)));
     }
     else {
-      $response->addCommand(new FieldFormCommand(drupal_render($form)));
-
-      $errors = form_get_errors();
-      if (count($errors)) {
-        $status_messages = array(
-          '#theme' => 'status_messages'
-        );
-        $response->addCommand(new FieldFormValidationErrorsCommand(drupal_render($status_messages)));
+      $form_state = array(
+        'langcode' => $langcode,
+        'no_redirect' => TRUE,
+        'build_info' => array('args' => array($entity, $field_name, $this->tempStoreFactory)),
+      );
+      $form = drupal_build_form('edit_field_form', $form_state);
+
+      if (!empty($form_state['executed'])) {
+        // The form submission saved the entity in tempstore. Return the
+        // updated view of the field from the tempstore copy.
+        $entity = $this->tempStoreFactory->get('edit')->get($entity->uuid());
+        $output = field_view_field($entity, $field_name, $view_mode_id, $langcode);
+
+        $response->addCommand(new FieldFormSavedCommand(drupal_render($output)));
+      }
+      else {
+        $response->addCommand(new FieldFormCommand(drupal_render($form)));
+
+        $errors = form_get_errors();
+        if (count($errors)) {
+          $status_messages = array(
+            '#theme' => 'status_messages'
+          );
+          $response->addCommand(new FieldFormValidationErrorsCommand(drupal_render($status_messages)));
+        }
       }
     }
 
@@ -248,7 +269,13 @@ public function entitySave(EntityInterface $entity) {
     // Take the entity from tempstore and save in entity storage. fieldForm()
     // ensures that the tempstore copy exists ahead.
     $tempstore = $this->tempStoreFactory->get('edit');
-    $tempstore->get($entity->uuid())->save();
+    $temp_entity = $tempstore->get($entity->uuid());
+    if ($temp_entity instanceof EntityChangedInterface && $entity->getChangedTime() != $temp_entity->getChangedTime()) {
+      // @todo freak out.
+    }
+    else {
+      $temp_entity->save();
+    }
     $tempstore->delete($entity->uuid());
 
     // Return information about the entity that allows a front end application
diff --git a/core/modules/edit/lib/Drupal/edit/Tests/EditLoadingTest.php b/core/modules/edit/lib/Drupal/edit/Tests/EditLoadingTest.php
index 7b01ade..82a194a 100644
--- a/core/modules/edit/lib/Drupal/edit/Tests/EditLoadingTest.php
+++ b/core/modules/edit/lib/Drupal/edit/Tests/EditLoadingTest.php
@@ -222,6 +222,45 @@ function testUserWithPermission() {
   }
 
   /**
+   * Tests Edit with concurrent node / Edit use.
+   */
+  function testConcurrentEdit() {
+    $this->drupalLogin($this->editor_user);
+
+    $response = $this->retrieveFieldForm('node/1/body/und/full');
+    $ajax_commands = drupal_json_decode($response);
+
+    // Prepare form values for submission. drupalPostAJAX() is not suitable
+    // for handling pages with JSON responses, so we need our own solution
+    // here.
+    $form_tokens_found = preg_match('/\sname="form_token" value="([^"]+)"/', $ajax_commands[0]['data'], $token_match) && preg_match('/\sname="form_build_id" value="([^"]+)"/', $ajax_commands[0]['data'], $build_id_match);
+    $this->assertTrue($form_tokens_found, 'Form tokens found in output.');
+
+    if ($form_tokens_found) {
+      $edit = array();
+      $edit['form_id'] = 'edit_field_form';
+      $edit['form_token'] = $token_match[1];
+      $edit['form_build_id'] = $build_id_match[1];
+      $edit['body[und][0][summary]'] = '';
+      $edit['body[und][0][value]'] = '<p>Fine thanks.</p>';
+      $edit['body[und][0][format]'] = 'filtered_html';
+      $edit['op'] = t('Save');
+
+      // Save the node on the regular node edit form.
+      $this->drupalPost('node/1/edit', array(), t('Save'));
+
+      // Submit field form and check response. Should throw a validation error
+      // because the node was changed in the meantime.
+      $response = $this->submitFieldForm('node/1/body/und/full', $edit);
+      $this->assertResponse(200);
+      $ajax_commands = drupal_json_decode($response);
+      $this->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
+      $this->assertIdentical('editFieldFormValidationErrors', $ajax_commands[0]['command'], 'The first AJAX command is an editFieldFormValidationErrors command.');
+      $this->assertTrue(strpos($ajax_commands[0]['data'], t('The copy of the content being edites is outdated. Reload the page to edit an up-to-date version.')), 'Error message returned to user.');
+    }
+  }
+
+  /**
    * Retrieve Edit metadata from the server. May also result in additional
    * JavaScript settings and CSS/JS being loaded.
    *
