diff --git a/entityreference.install b/entityreference.install
index 4e248ef..2f79947 100644
--- a/entityreference.install
+++ b/entityreference.install
@@ -18,11 +18,17 @@ function entityreference_field_schema($field) {
     $schema = array(
       'columns' => array(
         'target_id' => array(
-          'description' => 'The id of the target entity.',
+          'description' => 'The ID of the target entity.',
           'type' => 'int',
           'unsigned' => TRUE,
           'not null' => TRUE,
         ),
+        'revision_id' => array(
+          'description' => 'The revision ID of the target entity.',
+          'type' => 'int',
+          'unsigned' => TRUE,
+          'not null' => FALSE,
+        ),
       ),
       'indexes' => array(
         'target_id' => array('target_id'),
@@ -161,4 +167,34 @@ function entityreference_update_7002() {
       'not null' => TRUE,
     ));
   }
-}
\ No newline at end of file
+}
+
+/**
+ * Add "revision-id" to the field schema.
+ */
+function entityreference_update_7003() {
+  if (!module_exists('field_sql_storage')) {
+    return;
+  }
+  foreach (field_info_fields() as $field_name => $field) {
+    if ($field['type'] != 'entityreference' || $field['storage']['type'] !== 'field_sql_storage') {
+      // Not an entity reference field.
+      continue;
+    }
+
+    // Add the new column.
+    $field = field_info_field($field_name);
+    $table_name = _field_sql_storage_tablename($field);
+    $revision_name = _field_sql_storage_revision_tablename($field);
+
+    $spec = array(
+      'description' => 'The revision ID of the target entity.',
+      'type' => 'int',
+      'unsigned' => TRUE,
+      'not null' => FALSE,
+    );
+
+    db_add_field($table_name, $field_name . '_revision_id', $spec);
+    db_add_field($revision_name, $field_name . '_revision_id', $spec);
+  }
+}
diff --git a/entityreference.module b/entityreference.module
index f01ef7b..fc85690 100644
--- a/entityreference.module
+++ b/entityreference.module
@@ -243,6 +243,47 @@ function entityreference_field_validate($entity_type, $entity, $field, $instance
  * Adds the target type to the field data structure when saving.
  */
 function entityreference_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
+  if (!empty($field['settings']['handler_settings']['lock_revision'])) {
+    $dest_entity_type = $field['settings']['target_type'];
+    $original_items = array();
+    if (isset($entity->original)) {
+      $original_items = field_get_items($entity_type, $entity->original, $field['field_name']);
+    }
+    else {
+      $ids = entity_extract_ids($entity_type, $entity);
+      if ($ids[0]) {
+        $original = entity_load_unchanged($entity_type, $ids[0]);
+        if ($original) {
+          $original_items = field_get_items($entity_type, $original, $field['field_name']);
+        }
+      }
+    }
+    foreach ($items as $key => $val) {
+      // If the revision id is explicitly set, load the revision.
+      $ref_entity = FALSE;
+      if (isset($val['revision_id']) && $val['revision_id']) {
+        $ref_entity = entity_revision_load($dest_entity_type, $val['revision_id']);
+      }
+      // If the was not set or couldn't be loaded.
+      if (!$ref_entity) {
+        $ref_entity = entity_load_single($dest_entity_type, $val['target_id']);
+      }
+      $ref_ids = entity_extract_ids($dest_entity_type, $ref_entity);
+      // find the original item, which does not have the same delta per se.
+      $original_revision = FALSE;
+      foreach ($original_items as $original_item) {
+        if ($original_item['target_id'] == $val['target_id']) {
+          $original_revision = isset($original_item['revision_id']) ? $original_item['revision_id'] : FALSE;
+        }
+      }
+      if (isset($ref_ids[1]) && is_numeric($ref_ids[1]) && !$original_revision) {
+        $items[$key]['revision_id'] = $ref_ids[1];
+      }
+      else if ($original_revision) {
+        $items[$key]['revision_id'] = $original_revision;
+      }
+    }
+  }
   // Invoke the behaviors.
   foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) {
     $handler->presave($entity_type, $entity, $field, $instance, $langcode, $items);
@@ -672,12 +713,61 @@ function entityreference_field_property_callback(&$info, $entity_type, $field, $
   // Then apply the default.
   entity_metadata_field_default_property_callback($info, $entity_type, $field, $instance, $field_type);
 
+  // If the entity reference is locked to a revision, load that revision, not
+  // the current one.
+  if (!empty($field['settings']['handler_settings']['lock_revision'])) {
+    $name = $field['field_name'];
+    $property = &$info[$entity_type]['bundles'][$instance['bundle']]['properties'][$name];
+    $property['getter callback'] = 'entityreference_metadata_field_get_revision_data';
+    $property['setter callback'] = 'entityreference_metadata_field_set_revision_data';
+  }
+
   // Invoke the behaviors to allow them to change the properties.
   foreach (entityreference_get_behavior_handlers($field, $instance) as $handler) {
     $handler->property_info_alter($info, $entity_type, $field, $instance, $field_type);
   }
 }
 
+function entityreference_metadata_field_get_revision_data($entity, array $options, $name, $entity_type, $info){
+  $field = field_info_field($name);
+  $langcode = isset($options['language']) ? $options['language']->language : LANGUAGE_NONE;
+  $langcode = entity_metadata_field_get_language($entity_type, $entity, $field, $langcode, TRUE);
+  $values = array();
+  if (isset($entity->{$name}[$langcode])) {
+    foreach ($entity->{$name}[$langcode] as $delta => $data) {
+      if (isset($data['revision_id'])) {
+        $values[$delta] = array('id' => $data['target_id'], 'vid' => $data['revision_id']);
+      }
+      else {
+        $values[$delta] = $data['target_id'];
+      }
+    }
+  }
+  // For an empty single-valued field, we have to return NULL.
+  return $field['cardinality'] == 1 ? ($values ? reset($values) : NULL) : $values;
+}
+
+function entityreference_metadata_field_set_revision_data($entity, $name, $value, $langcode, $entity_type, $info) {
+  $field = field_info_field($name);
+  $langcode = entity_metadata_field_get_language($entity_type, $entity, $field, $langcode);
+  $values = $field['cardinality'] == 1 ? array($value) : (array) $value;
+
+  $items = array();
+  foreach ($values as $delta => $value) {
+    if (isset($value) && is_array($value)) {
+      $items[$delta]['target_id'] = $value['id'];
+      $items[$delta]['revision_id'] = $value['vid'];
+    }
+    else {
+      $items[$delta]['target_id'] = $value;
+    }
+  }
+  $entity->{$name}[$langcode] = $items;
+  // Empty the static field language cache, so the field system picks up any
+  // possible new languages.
+  drupal_static_reset('field_language');
+}
+
 /**
  * Implements hook_field_widget_info().
  */
@@ -1170,40 +1260,58 @@ function entityreference_field_formatter_settings_summary($field, $instance, $vi
  */
 function entityreference_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) {
   $target_ids = array();
+  $revision_ids = array();
 
   // Collect every possible entity attached to any of the entities.
   foreach ($entities as $id => $entity) {
     foreach ($items[$id] as $delta => $item) {
-      if (isset($item['target_id'])) {
+      if (!empty($item['revision_id'])) {
+        $revision_ids[] = $item['revision_id'];
+      }
+      elseif (!empty($item['target_id'])) {
         $target_ids[] = $item['target_id'];
       }
     }
   }
 
+  $target_type = $field['settings']['target_type'];
+
+  $target_entities = array();
+
   if ($target_ids) {
-    $target_entities = entity_load($field['settings']['target_type'], $target_ids);
+    $target_entities = entity_load($target_type, $target_ids);
   }
-  else {
-    $target_entities = array();
+
+  if ($revision_ids) {
+    // We need to load the revisions one by-one.
+    foreach ($revision_ids as $revision_id) {
+      $entity = entity_revision_load($target_type, $revision_id);
+      if ($entity) {
+        list($id) = entity_extract_ids($target_type, $entity);
+        // Use the revision-ID in the key.
+        $identifier = $id . ':' . $revision_id;
+        $target_entities[$identifier] = $entity;
+      }
+    }
   }
 
-  // Iterate through the fieldable entities again to attach the loaded data.
+  // Iterate through the fieldable entities again to attach the loaded
+  // data.
   foreach ($entities as $id => $entity) {
     $rekey = FALSE;
-
     foreach ($items[$id] as $delta => $item) {
-      // Check whether the referenced entity could be loaded.
-      if (isset($target_entities[$item['target_id']])) {
-        // Replace the instance value with the term data.
-        $items[$id][$delta]['entity'] = $target_entities[$item['target_id']];
-        // Check whether the user has access to the referenced entity.
-        $items[$id][$delta]['access'] = entity_access('view', $field['settings']['target_type'], $target_entities[$item['target_id']]);
-      }
-      // Otherwise, unset the instance value, since the entity does not exist.
-      else {
-        unset($items[$id][$delta]);
+      // If we have a revision-ID, the key uses it as-well.
+      $identifier = !empty($item['revision_id']) ? $item['target_id'] . ':' . $item['revision_id'] : $item['target_id'];
+      if (!isset($target_entities[$identifier])) {
+        // The entity no longer exists, so remove the key.
         $rekey = TRUE;
+        unset($items[$id][$delta]);
+        continue;
       }
+
+      $entity = $target_entities[$identifier];
+      $items[$id][$delta]['entity'] = $entity;
+      $items[$id][$delta]['access'] = entity_access('view', $target_type, $entity);
     }
 
     if ($rekey) {
diff --git a/plugins/selection/EntityReference_SelectionHandler_Generic.class.php b/plugins/selection/EntityReference_SelectionHandler_Generic.class.php
index 97d0174..a384f8b 100644
--- a/plugins/selection/EntityReference_SelectionHandler_Generic.class.php
+++ b/plugins/selection/EntityReference_SelectionHandler_Generic.class.php
@@ -149,6 +149,17 @@ class EntityReference_SelectionHandler_Generic implements EntityReference_Select
       );
     }
 
+    // Provide an option to lock the entity reference to the current revision if
+    // the entity supports it.
+    if (!empty($entity_info['revision table'])) {
+      $form['lock_revision'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Lock the field to the revision of the entity at the time it was referenced.'),
+        '#default_value' => !empty($field['settings']['handler_settings']['lock_revision']) ? TRUE : FALSE,
+        '#description' => t('When this is enabled, the reference will track the latest revision to that entity when this field is saved. This, combined with e.g. the <a href="!url">Workbench Moderation module</a>, can be used to provide limited workflow functionality around the referenced content.', array('!url' => 'http://drupal.org/project/workbench_moderation'))
+      );
+    }
+
     return $form;
   }
 
diff --git a/plugins/selection/EntityReference_SelectionHandler_Views.class.php b/plugins/selection/EntityReference_SelectionHandler_Views.class.php
index 1b036a7..60e569c 100644
--- a/plugins/selection/EntityReference_SelectionHandler_Views.class.php
+++ b/plugins/selection/EntityReference_SelectionHandler_Views.class.php
@@ -68,6 +68,18 @@ class EntityReference_SelectionHandler_Views implements EntityReference_Selectio
         )) . '</p>',
       );
     }
+
+    // Provide an option to lock the entity reference to the latest revision
+    // if the entity supports it.
+    if (!empty($entity_info['revision table'])) {
+      $form['lock_revision'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Lock the field to the revision of the entity at the time it was referenced.'),
+        '#default_value' => !empty($field['settings']['handler_settings']['lock_revision']) ? TRUE : FALSE,
+        '#description' => t('When this is enabled, the reference will track the latest revision to that entity when this field is saved. This, combined with e.g. the <a href="!url">Workbench Moderation module</a>, can be used to provide limited workflow functionality around the referenced content.', array('!url' => 'http://drupal.org/project/workbench_moderation'))
+      );
+    }
+
     return $form;
   }
 
diff --git a/views/entityreference.views.inc b/views/entityreference.views.inc
index df38395..25f026a 100644
--- a/views/entityreference.views.inc
+++ b/views/entityreference.views.inc
@@ -30,6 +30,26 @@ function entityreference_field_views_data($field) {
         'help' => t('A bridge to the @entity entity that is referenced via !field_name', $parameters),
       );
     }
+
+    if (isset($field['settings']['handler_settings']['lock_revision']) && $field['settings']['handler_settings']['lock_revision'] && isset($entity_info['revision table'])) {
+      $entity = $entity_info['label'];
+      if ($entity == t('Node')) {
+        $entity = t('Content');
+      }
+      $entity .= ' ' . t('Revision');
+
+      $field_name = $field['field_name'] . '_revision_id';
+      $parameters = array('@entity' => $entity, '!field_name' => $field['field_name']);
+      $data[$table_name][$field_name]['relationship'] = array(
+        'handler' => 'views_handler_relationship',
+        'base' => $entity_info['revision table'],
+        'base field' => $entity_info['entity keys']['revision'],
+        'label' => t('@entity entity revision referenced from !field_name', $parameters),
+        'group' => t('Entity Reference'),
+        'title' => t('Referenced Entity Revision'),
+        'help' => t('A bridge to the @entity entity revision that is referenced via !field_name', $parameters),
+      );
+    }
   }
 
   // Invoke the behaviors to allow them to change the properties.
