diff --git a/entity.test b/entity.test
index 6f8987e..1dc9d6e 100644
--- a/entity.test
+++ b/entity.test
@@ -60,6 +60,56 @@ class EntityAPITestCase extends DrupalWebTestCase {
   }
 
   /**
+   * Tests CRUD for entities support revisions.
+   */
+  function testCRUDRevisisions() {
+    module_enable(array('entity_feature'));
+
+    $user1 = $this->drupalCreateUser();
+    $user2 = $this->drupalCreateUser();
+
+    // Create a test entity.
+    $entity_initial = entity_create('entity_test_revision', array('name' => 'test', 'uid' => $user1->uid));
+    $entity_initial->save();
+
+    $entities = array_values(entity_load('entity_test_revision', FALSE));
+    $this->assertEqual(count($entities), 1, 'Entity created.');
+
+    // Saving the entity in revision mode should create a new revision.
+    $entity_bis = clone $entity_initial;
+    $entity_bis->uid = $user2->uid;
+    $entity_bis->revision = TRUE;
+    $entity_bis->save();
+    $this->assertNotEqual($entity_bis->rid, $entity_initial->rid, 'Saving an entity in revision mode creates a revision.');
+
+    // Check the saved entity.
+    $entities = entity_load('entity_test_revision', array($entity_initial->pid));
+    $entity = reset($entities);
+    $this->assertEqual($entity->uid, $user2->uid, 'Modifications to the entity were saved.');
+
+    // Check the initial revision.
+    $entities = entity_load('entity_test_revision', array($entity_initial->pid), array('rid' => $entity_initial->rid));
+    $entity = reset($entities);
+    $this->assertEqual($entity->uid, $user1->uid, 'Modifications to the entity have not affected the initial revision.');
+
+    // Saving the entity normally should not create a new revision.
+    $entity_ter = clone $entity_bis;
+    $entity_ter->uid = $user1->uid;
+    $entity_ter->save();
+    $this->assertEqual($entity_ter->rid, $entity_bis->rid, 'Saving an entity does not create a revision.');
+
+    // Check the saved entity.
+    $entities = entity_load('entity_test_revision', array($entity_initial->pid));
+    $entity = reset($entities);
+    $this->assertEqual($entity->uid, $user1->uid, 'Modifications to the entity were saved.');
+
+    // Delete the entity.
+    $entity_initial->delete();
+    $entities = array_values(entity_load('entity_test_revision', FALSE));
+    $this->assertEqual(count($entities), 0, 'Entity successfully deleted.');
+  }
+
+  /**
    * Tests CRUD API functions: entity_(create|delete|save)
    */
   function testCRUDAPIfunctions() {
diff --git a/includes/entity.controller.inc b/includes/entity.controller.inc
index 20bd3b8..c38b05a 100644
--- a/includes/entity.controller.inc
+++ b/includes/entity.controller.inc
@@ -346,19 +346,54 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit
 
       $this->invoke('presave', $entity);
 
-      if (!empty($entity->{$this->idKey}) && empty($entity->is_new)) {
+      // When saving a new revision, unset any existing revision ID so as to
+      // ensure that a new revision will actually be created, then store the old
+      // revision ID in a separate property for use by hook implementations.
+      if (!empty($this->revisionKey) && empty($entity->is_new) && !empty($entity->revision) && !empty($entity->{$this->revisionKey})) {
+        $entity->old_revision_id = $entity->{$this->revisionKey};
+        unset($entity->{$this->revisionKey});
+      }
+
+      if (empty($entity->{$this->idKey}) || !empty($entity->is_new)) {
+        // For new entities, create the row in the base table, then save the
+        // revision.
+        $return = drupal_write_record($this->entityInfo['base table'], $entity);
+        if (!empty($this->revisionKey)) {
+          drupal_write_record($this->entityInfo['revision table'], $entity);
+          $update_base_table = TRUE;
+        }
+        $this->invoke('insert', $entity);
+      }
+      else {
         $return = drupal_write_record($this->entityInfo['base table'], $entity, $this->idKey);
+
+        if (!empty($this->revisionKey)) {
+          if (!empty($entity->revision)) {
+            drupal_write_record($this->entityInfo['revision table'], $entity);
+            $update_base_table = TRUE;
+          }
+          else {
+            drupal_write_record($this->entityInfo['revision table'], $entity, $this->revisionKey);
+          }
+        }
+
         $this->resetCache(array($entity->{$this->idKey}));
         $this->invoke('update', $entity);
       }
-      else {
-        $return = drupal_write_record($this->entityInfo['base table'], $entity);
-        $this->invoke('insert', $entity);
+
+      if (!empty($update_base_table)) {
+        // Go back to the base table and update the pointer to the revision ID.
+        db_update($this->entityInfo['base table'])
+          ->fields(array($this->revisionKey => $entity->{$this->revisionKey}))
+          ->condition($this->idKey, $entity->{$this->idKey})
+          ->execute();
       }
+
       // Ignore slave server temporarily.
       db_ignore_slave();
       unset($entity->is_new);
       unset($entity->original);
+      unset($entity->revision);
 
       return $return;
     }
diff --git a/tests/entity_feature.module b/tests/entity_feature.module
index b626eae..dfc9252 100644
--- a/tests/entity_feature.module
+++ b/tests/entity_feature.module
@@ -30,3 +30,29 @@ function entity_feature_default_entity_test_type() {
 
   return $types;
 }
+
+/**
+ * Implements hook_default_entity_test_revision_type().
+ */
+function entity_feature_default_entity_test_revision_type() {
+  $types['main'] = entity_create('entity_test_revision_type', array(
+      'name' => 'main',
+      'label' => t('Main test type'),
+      'weight' => 0,
+      'locked' => TRUE,
+  ));
+
+  // Types used during CRUD testing.
+  $types['test'] = entity_create('entity_test_revision_type', array(
+    'name' => 'test',
+    'label' => 'label',
+    'weight' => 0,
+  ));
+  $types['test2'] = entity_create('entity_test_revision_type', array(
+      'name' => 'test2',
+      'label' => 'label2',
+      'weight' => 2,
+  ));
+
+  return $types;
+}
diff --git a/tests/entity_test.install b/tests/entity_test.install
index 55ce574..791adf7 100644
--- a/tests/entity_test.install
+++ b/tests/entity_test.install
@@ -133,5 +133,32 @@ function entity_test_schema() {
       'name' => array('name'),
     ),
   );
+
+  $schema['entity_test_revision'] = $schema['entity_test'];
+  $schema['entity_test_revision']['fields']['rid'] = array(
+    'type' => 'int',
+    'unsigned' => TRUE,
+    'not null' => FALSE,
+    'default' => NULL,
+    'description' => "The current revision ID of the entity.",
+  );
+
+  $schema['entity_test_revision_revision'] = $schema['entity_test'];
+  $schema['entity_test_revision_revision']['fields']['rid'] = array(
+    'type' => 'serial',
+    'not null' => TRUE,
+    'description' => 'Primary Key: Unique revision ID.',
+  );
+  $schema['entity_test_revision_revision']['fields']['pid'] = array(
+    'type' => 'int',
+    'unsigned' => TRUE,
+    'not null' => FALSE,
+    'default' => NULL,
+    'description' => "The ID of the attached entity.",
+  );
+  $schema['entity_test_revision_revision']['primary key'] = array('rid');
+
+  $schema['entity_test_revision_type'] = $schema['entity_test_type'];
+
   return $schema;
 }
diff --git a/tests/entity_test.module b/tests/entity_test.module
index 7e0878b..5f7d0ab 100644
--- a/tests/entity_test.module
+++ b/tests/entity_test.module
@@ -41,6 +41,40 @@ function entity_test_entity_info() {
         'name' => 'name',
       ),
     ),
+
+    'entity_test_revision' => array(
+      'label' => t('Test Entity (revision support)'),
+      'entity class' => 'EntityClassRevision',
+      'controller class' => 'EntityAPIController',
+      'base table' => 'entity_test_revision',
+      'revision table' => 'entity_test_revision_revision',
+      'fieldable' => TRUE,
+      'entity keys' => array(
+        'id' => 'pid',
+        'revision' => 'rid',
+        'bundle' => 'name',
+      ),
+      // Make use the class' label() and uri() implementation by default.
+      'label callback' => 'entity_class_label',
+      'uri callback' => 'entity_class_uri',
+      'bundles' => array(),
+      'bundle keys' => array(
+        'bundle' => 'name',
+      ),
+    ),
+    'entity_test_revision_type' => array(
+      'label' => t('Test entity type'),
+      'entity class' => 'Entity',
+      'controller class' => 'EntityAPIController',
+      'base table' => 'entity_test_revision_type',
+      'fieldable' => FALSE,
+      'bundle of' => 'entity_test_revision',
+      'exportable' => TRUE,
+      'entity keys' => array(
+        'id' => 'id',
+        'name' => 'name',
+      ),
+    ),
   );
   return $return;
 }
@@ -132,6 +166,16 @@ class EntityClass extends Entity {
   }
 }
 
+/**
+ * Main class for test entities (with revision support).
+ */
+class EntityClassRevision extends EntityClass {
+
+  public function __construct(array $values = array(), $entityType = NULL) {
+    Entity::__construct($values, 'entity_test_revision');
+  }
+
+}
 
 /**
  *
