diff --git a/metatag.module b/metatag.module
index 58362cc..7c64e42 100644
--- a/metatag.module
+++ b/metatag.module
@@ -379,7 +379,7 @@ function metatag_metatags_load_multiple($entity_type, array $entity_ids, array $
   while ($record = $result->fetchObject()) {
     // If requested, verify that only the appropriate revision records are
     // loaded.
-    if (empty($revision_ids) || array_key_exists($record->revision_id, $revision_ids)) {
+    if (empty($revision_ids) || in_array($record->revision_id, $revision_ids)) {
       $metatags[$record->entity_id][$record->revision_id][$record->language] = unserialize($record->data);
     }
   }
@@ -401,7 +401,7 @@ function metatag_metatags_load_multiple($entity_type, array $entity_ids, array $
  * @param $language
  *   The language of the translation set
  */
-function metatag_metatags_save($entity_type, $entity_id, $revision_id, $metatags, $langcode) {
+function metatag_metatags_save($entity_type, $entity_id, $revision_id, $metatags, $langcode, $old_vid = NULL) {
   // If no language assigned, use the has-no-language language.
   if (empty($langcode)) {
     $langcode = LANGUAGE_NONE;
@@ -447,6 +447,43 @@ function metatag_metatags_save($entity_type, $entity_id, $revision_id, $metatags
       ->execute();
   }
   else {
+    // We need to ensure that when we have multiple languages enabled
+    // that those languages get the incremented revision_id as well
+    // so that they can be loaded properly.
+    if (isset($old_vid)) {
+      $languages = language_list('enabled');
+      foreach ($languages[1] as $lang) {
+        if ($lang->language != $langcode) {
+          // Get all translations of tag data for this entity.
+          $result = db_query("SELECT data FROM {metatag} WHERE (entity_type = :type) AND (entity_id = :id) AND (language = :lang) AND (revision_id = :revision)", array(
+            ':type' => $entity_type,
+            ':id' => $entity_id,
+            ':lang' => $lang->language,
+            ':revision' => $old_vid,
+          ));
+          $metatag = array();
+          while ($record = $result->fetchObject()) {
+            $metatag = unserialize($record->data);
+          }
+          // Save the record.
+          if (!empty($metatag)) {
+            // Otherwise save the data for this entity.
+            db_merge('metatag')
+              ->key(array(
+                'entity_type' => $entity_type,
+                'entity_id' => $entity_id,
+                'language' => $lang->language,
+                'revision_id' => $revision_id,
+              ))
+              ->fields(array(
+                'data' => serialize($metatag),
+              ))
+              ->execute();
+          }
+        }
+      }
+    }
+
     // Otherwise save the data for this entity.
     db_merge('metatag')
       ->key(array(
@@ -611,7 +648,12 @@ function metatag_entity_insert($entity, $entity_type) {
       $langcode = LANGUAGE_NONE;
     }
 
-    metatag_metatags_save($entity_type, $entity_id, $revision_id, $entity->metatags, $langcode);
+    // Support for Metatag + Workbench Moderation.
+    if ($entity_type == 'node' && _metatag_isdefaultrevision($entity)) {
+      return;
+    }
+
+    metatag_metatags_save($entity_type, $entity_id, $revision_id, $entity->metatags, $langcode, $entity->old_vid);
   }
 }
 
@@ -647,8 +689,13 @@ function metatag_entity_update($entity, $entity_type) {
       }
     }
 
+    // Support for Metatag + Workbench Moderation.
+    if ($entity_type == 'node' && _metatag_isdefaultrevision($entity)) {
+      return;
+    }
+
     // Save the record.
-    metatag_metatags_save($entity_type, $entity_id, $revision_id, $entity->metatags, $new_language);
+    metatag_metatags_save($entity_type, $entity_id, $revision_id, $entity->metatags, $new_language, $entity->old_vid);
   }
   else {
     // Still ensure the meta tag output is cached.
@@ -1889,3 +1936,40 @@ function metatag_translate($name, $string, $langcode = NULL, $update = FALSE) {
     return $string;
   }
 }
+
+/**
+ * Checks if this entity is the default revision (published).
+ *
+ * @param object $entity
+ *   The entity object, e.g., $node.
+ *
+ * @return bool
+ *   TRUE if the entity is the default revision, FALSE otherwise.
+ */
+function _metatag_isdefaultrevision($entity) {
+  // D7 "Forward revisioning" is complex and causes a node_save() with the
+  // future node in node table. This fires hook_node_update() twice and cause
+  // abnormal behaviour in metatag.
+  //
+  // The steps taken by Workbench Moderation is to save the forward revision
+  // first and overwrite this with the live version in a shutdown function in
+  // a second step. This will confuse metatag. D7 has no generic property
+  // in the node object, if the node that is updated is the 'published' version
+  // or only a draft of a future version.
+  //
+  // This behaviour will change in D8 where $node->isDefaultRevision has been
+  // introduced. See below links for more details.
+  // - http://drupal.org/node/1879482
+  // - http://drupal.org/node/218755
+  // - http://drupal.org/node/1522154
+  //
+  // Every moderation module saving a forward revision needs to return FALSE.
+  // @todo: Refactor this workaround under D8.
+
+  // Workbench Moderation module.
+  if (module_exists('workbench_moderation') && workbench_moderation_node_type_moderated($entity->type) === TRUE && empty($entity->workbench_moderation['updating_live_revision'])) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
