diff --git a/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php b/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php
index b1fee2a294..b6391af4a9 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php
@@ -18,10 +18,31 @@ public function validate($entity, Constraint $constraint) {
       /** @var \Drupal\Core\Entity\EntityInterface $entity */
       if (!$entity->isNew()) {
         $saved_entity = \Drupal::entityManager()->getStorage($entity->getEntityTypeId())->loadUnchanged($entity->id());
-        // A change to any other translation must add a violation to the current
-        // translation because there might be untranslatable shared fields.
-        if ($saved_entity && $saved_entity->getChangedTimeAcrossTranslations() > $entity->getChangedTimeAcrossTranslations()) {
-          $this->context->addViolation($constraint->message);
+        // We have to ensure that all the entity translations match their
+        // current version in the storage in order to avoid reverting changes.
+        // A situation where the entity object contains an older entity
+        // translation version might occur when an entity translation is being
+        // concurrently edited. If the form that is being submitted last is not
+        // yet cached then on submitting it the entity will be retrieved from
+        // the entity storage and that entity object will be the updated one
+        // from the previous form submission. As a prevention of saving the
+        // entity resulting from the second submission the changed timestamp
+        // might be added to the form so that on submit it is set back on the
+        // entity object, which should be used to determine that a previous
+        // entity translation version has been edited and is currently being
+        // saved. We could compare only the latest changed timestamps across all
+        // translations to detect such cases. Unfortunatelly this comparison
+        // will not be sufficient if other translations of the entity have been
+        // edited and saved meanwhile, therefore we have to compare the changed
+        // timestamps of each entity translation individually.
+        if ($saved_entity) {
+          $common_translation_languages = array_intersect_key($entity->getTranslationLanguages(), $saved_entity->getTranslationLanguages());
+          foreach (array_keys($common_translation_languages) as $langcode) {
+            if ($saved_entity->getTranslation($langcode)->getChangedTime() > $entity->getTranslation($langcode)->getChangedTime()) {
+              $this->context->addViolation($constraint->message);
+              break;
+            }
+          }
         }
       }
     }
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityValidationTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityValidationTest.php
index bf2a147e0a..5289942b1c 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityValidationTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityValidationTest.php
@@ -3,6 +3,7 @@
 namespace Drupal\KernelTests\Core\Entity;
 
 use Drupal\Core\Entity\Plugin\Validation\Constraint\CompositeConstraintBase;
+use Drupal\language\Entity\ConfigurableLanguage;
 
 /**
  * Tests the Entity Validation API.
@@ -16,7 +17,7 @@ class EntityValidationTest extends EntityKernelTestBase {
    *
    * @var array
    */
-  public static $modules = ['filter', 'text'];
+  public static $modules = ['filter', 'text', 'language'];
 
   /**
    * @var string
@@ -39,6 +40,10 @@ class EntityValidationTest extends EntityKernelTestBase {
   protected function setUp() {
     parent::setUp();
 
+    // Enable an additional language.
+    ConfigurableLanguage::createFromLangcode('de')
+      ->save();
+
     // Create the test field.
     module_load_install('entity_test');
     entity_test_install();
@@ -200,4 +205,47 @@ public function testCompositeConstraintValidation() {
     $this->assertEqual($constraint->coversFields(), ['name', 'type'], 'Information about covered fields can be retrieved.');
   }
 
+  /**
+   * Tests the EntityChangedConstraintValidator.
+   */
+  public function testEntityChangedConstraintOnFormConcurrentEditing() {
+    $this->installEntitySchema('entity_test_mulrev_changed');
+    $storage = \Drupal::entityTypeManager()
+      ->getStorage('entity_test_mulrev_changed');
+
+    // Create a test entity.
+    $entity = $this->createTestEntity('entity_test_mulrev_changed');
+    $entity->save();
+
+    $entity->setChangedTime($entity->getChangedTime() - 1);
+    $violations = $entity->validate();
+    $this->assertEquals(1, $violations->count());
+    $this->assertEqual($violations[0]->getMessage(), 'The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.');
+
+    $entity = $storage->loadUnchanged($entity->id());
+    $translation = $entity->addTranslation('de');
+    $entity->save();
+
+    $this->assertNotEquals($entity->getChangedTime(), $translation->getChangedTime());
+
+    // Simulate concurrent form editing by saving the entity with an altered
+    // non-translatable field in order for the changed timestamp to be updated
+    // across all entity translations. Afterwards we simulate form submitting of
+    // an uncached form by setting the previous timestamp of an entity
+    // translation on the saved entity object. This is what happens in the
+    // entity form API where we put the changed timestamp of the entity in a
+    // form hidden value and then set it on the entity which on form submit is
+    // loaded from the storage. Setting the initial changed timestamp on the
+    // entity loaded from the storage is used as a prevention from saving a form
+    // built with a previous version of the entity and thus reverting changes by
+    // other users.
+    $original_entity_time = $entity->getChangedTime();
+    $entity->set('not_translatable', $this->randomString());
+    $entity->save();
+    $entity->setChangedTime($original_entity_time);
+    $violations = $entity->validate();
+    $this->assertEquals(1, $violations->count());
+    $this->assertEqual($violations[0]->getMessage(), 'The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.');
+  }
+
 }
