diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index cac428f..9cab589 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -392,7 +392,7 @@ function _comment_body_field_create($info) {
  * Implements hook_permission().
  */
 function comment_permission() {
-  return array(
+  $permissions = array(
     'administer comments' => array(
       'title' => t('Administer comments and comment settings'),
     ),
@@ -409,6 +409,14 @@ function comment_permission() {
       'title' => t('Edit own comments'),
     ),
   );
+
+  if (module_exists('translation_entity') && translation_entity_enabled('comment')) {
+    $permissions['translate comments'] = array(
+      'title' => t('Translate comments'),
+    );
+  }
+
+  return $permissions;
 }
 
 /**
diff --git a/core/modules/comment/lib/Drupal/comment/CommentTranslationController.php b/core/modules/comment/lib/Drupal/comment/CommentTranslationController.php
index 0cfa52b..0c7d1c0 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentTranslationController.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentTranslationController.php
@@ -17,6 +17,30 @@
 class CommentTranslationController extends EntityTranslationController {
 
   /**
+   * Overrides EntityTranslationController::getAccess().
+   */
+  public function getAccess(EntityInterface $entity, $op) {
+    switch ($op) {
+      case 'view':
+        return user_access('access comments');
+      case 'update':
+        return comment_access('edit', $entity);
+      case 'delete':
+        return user_access('administer comments');
+      case 'create':
+        return user_access('post comments');
+    }
+    return parent::getAccess($entity, $op);
+  }
+
+  /**
+   * Overrides EntityTranslationController::getTranslationAccess().
+   */
+  public function getTranslationAccess(EntityInterface $entity, $op) {
+    return user_access('translate comments') && parent::getTranslationAccess($entity, $op);
+  }
+
+  /**
    * Overrides EntityTranslationController::entityFormTitle().
    */
   protected function entityFormTitle(EntityInterface $entity) {
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php
index 7dfb02e..97614b4 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentTranslationUITest.php
@@ -58,7 +58,7 @@ function setupBundle() {
    * Overrides \Drupal\translation_entity\Tests\EntityTranslationUITest::getTranslatorPermission().
    */
   function getTranslatorPermissions() {
-    return array('post comments', 'administer comments', "translate $this->entityType entities", 'edit original values');
+    return array_merge(parent::getTranslatorPermissions(), array('post comments', 'administer comments', 'translate comments'));
   }
 
   /**
@@ -99,7 +99,7 @@ protected function getNewEntityValues($langcode) {
    * Tests translate link on comment content admin page.
    */
   function testTranslateLinkCommentAdminPage() {
-    $this->admin_user = $this->drupalCreateUser(array('access administration pages', 'administer comments', 'translate any entity'));
+    $this->admin_user = $this->drupalCreateUser(array_merge(parent::getTranslatorPermissions(), array('access administration pages', 'administer comments')));
     $this->drupalLogin($this->admin_user);
 
     $cid_translatable = $this->createEntity(array(), $this->langcodes[0], $this->nodeBundle);
diff --git a/core/modules/node/lib/Drupal/node/NodeTranslationController.php b/core/modules/node/lib/Drupal/node/NodeTranslationController.php
index da078ac..0b5977f 100644
--- a/core/modules/node/lib/Drupal/node/NodeTranslationController.php
+++ b/core/modules/node/lib/Drupal/node/NodeTranslationController.php
@@ -23,6 +23,13 @@ public function getAccess(EntityInterface $entity, $op) {
   }
 
   /**
+   * Overrides EntityTranslationController::getTranslationAccess().
+   */
+  public function getTranslationAccess(EntityInterface $entity, $op) {
+    return user_access("translate any {$entity->bundle()} content") && parent::getTranslationAccess($entity, $op);
+  }
+
+  /**
    * Overrides EntityTranslationController::entityFormAlter().
    */
   public function entityFormAlter(array &$form, array &$form_state, EntityInterface $entity) {
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php
index 8cd5b49..3f215a0 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php
@@ -56,7 +56,7 @@ protected function setupBundle() {
    * Overrides \Drupal\translation_entity\Tests\EntityTranslationUITest::getTranslatorPermission().
    */
   function getTranslatorPermissions() {
-    return array("edit any $this->bundle content", "translate $this->entityType entities", 'edit original values');
+    return array_merge(parent::getTranslatorPermissions(), array("edit any $this->bundle content", "translate any $this->bundle content"));
   }
 
   /**
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index bdfae92..4310305 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -2862,6 +2862,13 @@ function node_list_permissions($type) {
       'title' => t('%type_name: Delete any content', array('%type_name' => $type->name)),
     ),
   );
+
+  if (module_exists('translation_entity') && translation_entity_enabled('node', $type->type)) {
+    $perms["translate any $type->type content"] = array(
+      'title' => t('%type_name: Translate any content', array('%type_name' => $type->name)),
+    );
+  }
+
   return $perms;
 }
 
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermTranslationController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermTranslationController.php
index 2fa4227..7751097 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermTranslationController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermTranslationController.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\taxonomy;
 
+use Drupal\taxonomy\Plugin\Core\Entity\Term;
+
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\translation_entity\EntityTranslationController;
 
@@ -16,6 +18,27 @@
 class TermTranslationController extends EntityTranslationController {
 
   /**
+   * Overrides EntityTranslationController::getAccess().
+   */
+  public function getAccess(EntityInterface $entity, $op) {
+    switch ($op) {
+      case 'create':
+      case 'update':
+        return taxonomy_term_access('edit', $entity);
+      case 'delete':
+        return taxonomy_term_access('delete', $entity);
+    }
+    return parent::getAccess($entity, $op);
+  }
+
+  /**
+   * Overrides EntityTranslationController::getTranslationAccess().
+   */
+  public function getTranslationAccess(EntityInterface $entity, $op) {
+    return user_access("translate terms in $entity->vid") && parent::getTranslationAccess($entity, $op);
+  }
+
+  /**
    * Overrides EntityTranslationController::entityFormAlter().
    */
   public function entityFormAlter(array &$form, array &$form_state, EntityInterface $entity) {
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTranslationUITest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTranslationUITest.php
index 043defc..9c7ee00 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTranslationUITest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTranslationUITest.php
@@ -73,7 +73,8 @@ protected function setupBundle() {
    * Overrides \Drupal\translation_entity\Tests\EntityTranslationUITest::getTranslatorPermission().
    */
   function getTranslatorPermissions() {
-    return array('administer taxonomy', "translate $this->entityType entities", 'edit original values');
+    $vocabulary = taxonomy_vocabulary_machine_name_load($this->bundle);
+    return array_merge(parent::getTranslatorPermissions(), array('administer taxonomy', 'translate terms in ' . $vocabulary->id()));
   }
 
   /**
@@ -117,7 +118,7 @@ public function testTranslationUI() {
    * Tests translate link on vocabulary term list.
    */
   function testTranslateLinkVocabularyAdminPage() {
-    $this->admin_user = $this->drupalCreateUser(array('access administration pages', 'administer taxonomy', 'translate any entity'));
+    $this->admin_user = $this->drupalCreateUser(array_merge(parent::getTranslatorPermissions(), array('access administration pages', 'administer taxonomy')));
     $this->drupalLogin($this->admin_user);
 
     $translatable_vocabulary_name = $this->vocabulary->name;
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index 0158e7e..5287896 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -101,6 +101,13 @@ function taxonomy_permission() {
          'title' => t('Delete terms from %vocabulary', array('%vocabulary' => $vocabulary->name)),
       ),
     );
+    if (module_exists('translation_entity') && translation_entity_enabled('taxonomy_term', $vocabulary->machine_name)) {
+      $permissions += array(
+         'translate terms in ' . $vocabulary->vid => array(
+           'title' => t('Translate terms from %vocabulary', array('%vocabulary' => $vocabulary->name)),
+        ),
+      );
+    }
   }
   return $permissions;
 }
diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php b/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php
index b08518a..77ffbbf 100644
--- a/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php
+++ b/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php
@@ -99,9 +99,8 @@ public function getAccess(EntityInterface $entity, $op) {
   /**
    * Implements EntityTranslationControllerInterface::getTranslationAccess().
    */
-  public function getTranslationAccess(EntityInterface $entity, $langcode) {
-    $entity_type = $entity->entityType();
-    return (user_access('translate any entity') || user_access("translate $entity_type entities")) && ($langcode != $entity->language()->langcode || user_access('edit original values'));
+  public function getTranslationAccess(EntityInterface $entity, $op) {
+    return user_access("$op entity translations");
   }
 
   /**
@@ -203,6 +202,7 @@ public function entityFormAlter(array &$form, array &$form_state, EntityInterfac
           '#value' => t('Delete translation'),
           '#weight' => $weight,
           '#submit' => array(array($this, 'entityFormDeleteTranslation')),
+          '#access' => $this->getTranslationAccess($entity, 'delete'),
         );
       }
 
@@ -220,7 +220,7 @@ public function entityFormAlter(array &$form, array &$form_state, EntityInterfac
         '#collapsed' => TRUE,
         '#tree' => TRUE,
         '#weight' => 10,
-        '#access' => $this->getTranslationAccess($entity, $form_langcode),
+        '#access' => $this->getTranslationAccess($entity, $source_langcode ? 'create' : 'update'),
         '#multilingual' => TRUE,
       );
 
@@ -259,17 +259,11 @@ public function entityFormAlter(array &$form, array &$form_state, EntityInterfac
   }
 
   /**
-   * Process callback: Determines which elements get clue in the form.
-   *
-   * @param array $element
-   *   Form API element.
-   *
-   * @return array
-   *   A processed element with the shared elements marked with a clue.
+   * Process callback: determines which elements get clue in the form.
    *
    * @see \Drupal\translation_entity\EntityTranslationController::entityFormAlter()
    */
-  public function entityFormSharedElements($element) {
+  public function entityFormSharedElements($element, $form_state, $form) {
     static $ignored_types;
 
     // @todo Find a more reliable way to determine if a form element concerns a
@@ -280,7 +274,7 @@ public function entityFormSharedElements($element) {
 
     foreach (element_children($element) as $key) {
       if (!isset($element[$key]['#type'])) {
-        $this->entityFormSharedElements($element[$key]);
+        $this->entityFormSharedElements($element[$key], $form_state, $form);
       }
       else {
         // Ignore non-widget form elements.
@@ -289,7 +283,15 @@ public function entityFormSharedElements($element) {
         }
         // Elements are considered to be non multilingual by default.
         if (empty($element[$key]['#multilingual'])) {
-          $this->addTranslatabilityClue($element[$key]);
+          // If we are displaying a multilingual entity form we need to provide
+          // transltability clues, otherwise the shared form elements should be
+          // hidden.
+          if (empty($form_state['translation_entity']['translation_form'])) {
+            $this->addTranslatabilityClue($element[$key]);
+          }
+          else {
+            $element[$key]['#access'] = FALSE;
+          }
         }
       }
     }
diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationControllerInterface.php b/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationControllerInterface.php
index ed08fc0..05e719d 100644
--- a/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationControllerInterface.php
+++ b/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationControllerInterface.php
@@ -132,17 +132,22 @@ public function getViewPath(EntityInterface $entity);
   public function getAccess(EntityInterface $entity, $op);
 
   /**
-   * Checks if a user is allowed to edit the given translation.
+   * Checks if the user can perform the given operation on translations of the
+   * wrapped entity.
    *
    * @param \Drupal\Core\Entity\EntityInterface $entity
    *   The entity whose translation has to be accessed.
-   * @param string $langcode
-   *   The language code identifying the translation to be accessed.
+   * @param $op
+   *   The operation to be performed on the translation. Possible values are:
+   *   - "view"
+   *   - "update"
+   *   - "delete"
+   *   - "create"
    *
    * @return boolean
    *   TRUE if the operation may be performed, FALSE otherwise.
    */
-  public function getTranslationAccess(EntityInterface $entity, $langcode);
+  public function getTranslationAccess(EntityInterface $entity, $op);
 
   /**
    * Retrieves the source language for the translation being created.
diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/ConfigTestTranslationUITest.php b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/ConfigTestTranslationUITest.php
index 7d5a38b..4d5fead 100644
--- a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/ConfigTestTranslationUITest.php
+++ b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/ConfigTestTranslationUITest.php
@@ -41,7 +41,7 @@ function setUp() {
    * Overrides \Drupal\translation_entity\Tests\EntityTranslationUITest::getTranslatorPermission().
    */
   function getTranslatorPermissions() {
-    return array("translate $this->entityType entities", 'edit original values');
+    return array('access entity translation overview', 'create entity translations', 'update entity translations', 'delete entity translations');
   }
 
   /**
diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTestTranslationUITest.php b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTestTranslationUITest.php
index f66fcc3..8c7ec7c 100644
--- a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTestTranslationUITest.php
+++ b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTestTranslationUITest.php
@@ -39,7 +39,7 @@ function setUp() {
    * Overrides \Drupal\translation_entity\Tests\EntityTranslationUITest::getTranslatorPermission().
    */
   function getTranslatorPermissions() {
-    return array('administer entity_test content', "translate $this->entityType entities", 'edit original values');
+    return array_merge(parent::getTranslatorPermissions(), array('administer entity_test content'));
   }
 
   /**
diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationUITest.php b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationUITest.php
index eac0b7f..5de40ce 100644
--- a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationUITest.php
+++ b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationUITest.php
@@ -103,7 +103,9 @@ protected function enableTranslation() {
   /**
    * Returns an array of permissions needed for the translator.
    */
-  abstract function getTranslatorPermissions();
+  function getTranslatorPermissions() {
+    return array('access entity translation overview', 'create entity translations', 'update entity translations', 'delete entity translations');
+  }
 
   /**
    * Creates and activates a translator user.
diff --git a/core/modules/translation_entity/translation_entity.module b/core/modules/translation_entity/translation_entity.module
index dac1001..05136a3 100644
--- a/core/modules/translation_entity/translation_entity.module
+++ b/core/modules/translation_entity/translation_entity.module
@@ -135,18 +135,37 @@ function translation_entity_menu() {
         'weight' => 2,
       ) + $item;
 
+      $items["$path/translations/overview"] = array(
+        'title' => 'Overview',
+        'type' => MENU_DEFAULT_LOCAL_TASK,
+        'weight' => 0,
+      );
+
       // Add translation callback.
       // @todo Add the access callback instead of replacing it as soon as the
       // routing system supports multiple callbacks.
-      $add_path = "$path/translations/add/%language/%language";
       $language_position = $entity_position + 3;
       $args = array($entity_position, $language_position, $language_position + 1);
-      $items[$add_path] = array(
+      $items["$path/translations/add/%language/%language"] = array(
         'title' => 'Add',
         'page callback' => 'translation_entity_add_page',
         'page arguments' => $args,
         'access callback' => 'translation_entity_add_access',
         'access arguments' => $args,
+        'type' => MENU_LOCAL_TASK,
+        'weight' => 1,
+      ) + $item;
+
+      // Edit translation callback.
+      $args = array($entity_position, $language_position);
+      $items["$path/translations/edit/%language"] = array(
+        'title' => 'Edit',
+        'page callback' => 'translation_entity_edit_page',
+        'page arguments' => $args,
+        'access callback' => 'translation_entity_edit_access',
+        'access arguments' => $args,
+        'type' => MENU_LOCAL_TASK,
+        'weight' => 1,
       ) + $item;
 
       // Delete translation callback.
@@ -154,6 +173,8 @@ function translation_entity_menu() {
         'title' => 'Delete',
         'page callback' => 'drupal_get_form',
         'page arguments' => array('translation_entity_delete_confirm', $entity_position, $language_position),
+        'access callback' => 'translation_entity_delete_access',
+        'access arguments' => $args,
       ) + $item;
     }
   }
@@ -231,7 +252,7 @@ function translation_entity_menu_alter(array &$items) {
  */
 function translation_entity_translate_access(EntityInterface $entity) {
   $entity_type = $entity->entityType();
-  return empty($entity->language()->locked) && language_multilingual() && translation_entity_enabled($entity_type, $entity->bundle()) && (user_access('translate any entity') || user_access("translate $entity_type entities"));
+  return empty($entity->language()->locked) && language_multilingual() && translation_entity_enabled($entity_type, $entity->bundle()) && user_access('access entity translation overview');
 }
 
 /**
@@ -240,16 +261,50 @@ function translation_entity_translate_access(EntityInterface $entity) {
  * @param \Drupal\Core\Entity\EntityInterface $entity
  *   The entity being translated.
  * @param \Drupal\Core\Language\Language $source
- *   The language of the values being translated.
+ *   (optional) The language of the values being translated. Defaults to the
+ *   entity language.
  * @param \Drupal\Core\Language\Language $target
- *   The language of the translated values.
+ *   (optional) The language of the translated values. Defaults to the current
+ *   content language.
  */
 function translation_entity_add_access(EntityInterface $entity, Language $source = NULL, Language $target = NULL) {
   $source = !empty($source) ? $source : $entity->language();
   $target = !empty($target) ? $target : language(LANGUAGE_TYPE_CONTENT);
   $translations = $entity->getTranslationLanguages();
   $languages = language_list();
-  return $source->langcode != $target->langcode && isset($languages[$source->langcode]) && isset($languages[$target->langcode]) && !isset($translations[$target->langcode]) && translation_entity_access($entity, $target->langcode);
+  return $source->langcode != $target->langcode && isset($languages[$source->langcode]) && isset($languages[$target->langcode]) && !isset($translations[$target->langcode]) && translation_entity_access($entity, 'create');
+}
+
+/**
+ * Access callback for the translation edit page.
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ *   The entity being translated.
+ * @param \Drupal\Core\Language\Language $language
+ *   (optional) The language of the translated values. Defaults to the current
+ *   content language.
+ */
+function translation_entity_edit_access(EntityInterface $entity, Language $language = NULL) {
+  $language = !empty($language) ? $language : language(LANGUAGE_TYPE_CONTENT);
+  $translations = $entity->getTranslationLanguages();
+  $languages = language_list();
+  return isset($languages[$language->langcode]) && $language != $entity->language() && isset($translations[$language->langcode]) && translation_entity_access($entity, 'update');
+}
+
+/**
+ * Access callback for the translation delete page.
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ *   The entity being translated.
+ * @param \Drupal\Core\Language\Language $language
+ *   (optional) The language of the translated values. Defaults to the current
+ *   content language.
+ */
+function translation_entity_delete_access(EntityInterface $entity, Language $language = NULL) {
+  $language = !empty($language) ? $language : language(LANGUAGE_TYPE_CONTENT);
+  $translations = $entity->getTranslationLanguages();
+  $languages = language_list();
+  return isset($languages[$language->langcode]) && $language != $entity->language() && isset($translations[$language->langcode]) && translation_entity_access($entity, 'delete');
 }
 
 /**
@@ -376,46 +431,45 @@ function translation_entity_form_controller(array $form_state) {
  *
  * @param \Drupal\Core\Entity\EntityInterface $entity
  *   The entity to be accessed.
- * @param string $langcode
- *   The language of the translation to be accessed.
+ * @param $op
+ *   The operation to be performed on the translation. Possible values are:
+ *   - "view"
+ *   - "update"
+ *   - "delete"
+ *   - "create"
  *
  * @return
  *   TRUE if the current user is allowed to view the translation.
  */
-function translation_entity_access(EntityInterface $entity, $langcode) {
-  return translation_entity_controller($entity->entityType())->getTranslationAccess($entity, $langcode) ;
+function translation_entity_access(EntityInterface $entity, $op) {
+  return translation_entity_controller($entity->entityType())->getTranslationAccess($entity, $op) ;
 }
 
 /**
  * Implements hook_permission().
  */
 function translation_entity_permission() {
-  $permission = array(
-    'edit original values' => array(
-      'title' => t('Edit original values'),
-      'description' => t('Access the entity form in the original language.'),
-    ),
+  return array(
     'toggle field translatability' => array(
       'title' => t('Toggle field translatability'),
       'description' => t('Toggle translatability of fields performing a bulk update.'),
     ),
-    'translate any entity' => array(
-      'title' => t('Translate any entity'),
-      'description' => t('Translate field content for any fieldable entity.'),
+    'access entity translation overview' => array(
+      'title' => t('Access translation overview'),
+    ),
+    'view entity translations' => array(
+      'title' => t('Access translations'),
+    ),
+    'create entity translations' => array(
+      'title' => t('Create translations'),
+    ),
+    'update entity translations' => array(
+      'title' => t('Edit translations'),
+    ),
+    'delete entity translations' => array(
+      'title' => t('Delete translations'),
     ),
   );
-
-  foreach (entity_get_info() as $entity_type => $info) {
-    if (translation_entity_enabled($entity_type)) {
-      $label = !empty($info['label']) ? t($info['label']) : $entity_type;
-      $permission["translate $entity_type entities"] = array(
-        'title' => t('Translate entities of type @type', array('@type' => $label)),
-        'description' => t('Translate field content for entities of type @type.', array('@type' => $label)),
-      );
-    }
-  }
-
-  return $permission;
 }
 
 /**
diff --git a/core/modules/translation_entity/translation_entity.pages.inc b/core/modules/translation_entity/translation_entity.pages.inc
index 294c97b..f52632f 100644
--- a/core/modules/translation_entity/translation_entity.pages.inc
+++ b/core/modules/translation_entity/translation_entity.pages.inc
@@ -51,11 +51,13 @@ function translation_entity_overview(EntityInterface $entity) {
       $language_name = $language->name;
       $langcode = $language->langcode;
       $add_path = $base_path . '/translations/add/' . $original . '/' . $langcode;
+      $translate_path = $base_path . '/translations/edit/' . $langcode;
       $delete_path = $base_path . '/translations/delete/' . $langcode;
 
       if ($base_path) {
         $add_links = _translation_entity_get_switch_links($add_path);
         $edit_links = _translation_entity_get_switch_links($edit_path);
+        $translate_links = _translation_entity_get_switch_links($translate_path);
         $delete_links = _translation_entity_get_switch_links($delete_path);
       }
 
@@ -80,8 +82,17 @@ function translation_entity_overview(EntityInterface $entity) {
           $row_title = $is_original ? $label : t('n/a');
         }
 
-        if ($edit_path && $controller->getAccess($entity, 'update') && $controller->getTranslationAccess($entity, $langcode)) {
+        // If the user is allowed to edit the entity we point the edit link to
+        // the entity form, otherwise if we are not dealing with the original
+        // language we point the link to the translation form.
+        if ($edit_path && $controller->getAccess($entity, 'update')) {
           $links['edit'] = isset($edit_links->links[$langcode]['href']) ? $edit_links->links[$langcode] : array('href' => $edit_path, 'language' => $language);
+        }
+        elseif (!$is_original && $controller->getTranslationAccess($entity, 'update')) {
+          $links['edit'] = isset($translate_links->links[$langcode]['href']) ? $translate_links->links[$langcode] : array('href' => $translate_path, 'language' => $language);
+        }
+
+        if (isset($links['edit'])) {
           $links['edit']['title'] = t('edit');
         }
 
@@ -98,8 +109,10 @@ function translation_entity_overview(EntityInterface $entity) {
         }
         else {
           $source_name = isset($languages[$source]) ? $languages[$source]->name : t('n/a');
-          $links['delete'] = isset($delete_links->links[$langcode]['href']) ? $delete_links->links[$langcode] : array('href' => $delete_links, 'language' => $language);
-          $links['delete']['title'] = t('delete');
+          if ($controller->getTranslationAccess($entity, 'delete')) {
+            $links['delete'] = isset($delete_links->links[$langcode]['href']) ? $delete_links->links[$langcode] : array('href' => $delete_links, 'language' => $language);
+            $links['delete']['title'] = t('delete');
+          }
         }
       }
       else {
@@ -107,7 +120,7 @@ function translation_entity_overview(EntityInterface $entity) {
         $row_title = $source_name = t('n/a');
         $source = $entity->language()->langcode;
 
-        if ($source != $langcode && $controller->getAccess($entity, 'update')) {
+        if ($source != $langcode && $controller->getTranslationAccess($entity, 'create')) {
           if ($translatable) {
             $links['add'] = isset($add_links->links[$langcode]['href']) ? $add_links->links[$langcode] : array('href' => $add_path, 'language' => $language);
             $links['add']['title'] = t('add');
@@ -193,6 +206,27 @@ function translation_entity_add_page(EntityInterface $entity, Language $source =
 }
 
 /**
+ * Page callback for the translation edit page.
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ *   The entity being translated.
+ * @param \Drupal\Core\Language\Language $language
+ *   (optional) The language of the translated values. Defaults to the current
+ *   content language.
+ *
+ * @return array
+ *   A processed form array ready to be rendered.
+ */
+function translation_entity_edit_page(EntityInterface $entity, Language $language = NULL) {
+  $language = !empty($language) ? $language : language(LANGUAGE_TYPE_CONTENT);
+  $info = $entity->entityInfo();
+  $operation = isset($info['default_operation']) ? $info['default_operation'] : 'default';
+  $form_state = entity_form_state_defaults($entity, $operation, $language->langcode);
+  $form_state['translation_entity']['translation_form'] = TRUE;
+  $form_id = entity_form_id($entity);
+  return drupal_build_form($form_id, $form_state);
+}
+/**
  * Populates target values with the source values.
  *
  * @param \Drupal\Core\Entity\EntityInterface $entity
diff --git a/core/modules/user/lib/Drupal/user/Tests/UserTranslationUITest.php b/core/modules/user/lib/Drupal/user/Tests/UserTranslationUITest.php
index 1b6160a..72ffcaa 100644
--- a/core/modules/user/lib/Drupal/user/Tests/UserTranslationUITest.php
+++ b/core/modules/user/lib/Drupal/user/Tests/UserTranslationUITest.php
@@ -48,7 +48,7 @@ function setUp() {
    * Overrides \Drupal\translation_entity\Tests\EntityTranslationUITest::getTranslatorPermission().
    */
   function getTranslatorPermissions() {
-    return array('administer users', "translate $this->entityType entities", 'edit original values');
+    return array_merge(parent::getTranslatorPermissions(), array('administer users'));
   }
 
   /**
@@ -63,7 +63,7 @@ protected function getNewEntityValues($langcode) {
    * Tests translate link on user admin list.
    */
   function testTranslateLinkUserAdminPage() {
-    $this->admin_user = $this->drupalCreateUser(array('access administration pages', 'administer users', 'translate any entity'));
+    $this->admin_user = $this->drupalCreateUser(array_merge(parent::getTranslatorPermissions(), array('access administration pages', 'administer users')));
     $this->drupalLogin($this->admin_user);
 
     $uid = $this->createEntity(array('name' => $this->randomName()), $this->langcodes[0]);
