diff --git a/modules/field/field.api.php b/modules/field/field.api.php
index 129a915d27..3c77b82eba 100644
--- a/modules/field/field.api.php
+++ b/modules/field/field.api.php
@@ -278,6 +278,32 @@ function hook_field_schema($field) {
   );
 }
 
+/**
+ * Allow modules to alter the schema for a field.
+ *
+ * @param array $schema
+ *   The schema definition as returned by hook_field_schema().
+ * @param array $field
+ *   The field definition.
+ *
+ * @see field_retrieve_schema()
+ */
+function hook_field_schema_alter(&$schema, $field) {
+  if ($field['type'] == 'image') {
+    // Alter the length of a field.
+    $schema['columns']['alt']['length'] = 2048;
+    // Add an additional column of data.
+    $schema['columns']['additional_column'] = array(
+      'description' => "Additional column added to image field table.",
+      'type' => 'varchar',
+      'length' => 128,
+      'not null' => FALSE,
+    );
+    // Add an additional index.
+    $schema['indexes']['fid_additional_column'] = array('fid', 'additional_column');
+  }
+}
+
 /**
  * Define custom load behavior for this module's field types.
  *
diff --git a/modules/field/field.crud.inc b/modules/field/field.crud.inc
index 3673128d08..9b28ac5222 100644
--- a/modules/field/field.crud.inc
+++ b/modules/field/field.crud.inc
@@ -20,6 +20,26 @@
  * the Field API.
  */
 
+/**
+ * Retrieves the schema for a field.
+ *
+ * @param array $field
+ *   The field array to get the schema definition against.
+ * @return array
+ *   The field schema definition array.
+ */
+function field_retrieve_schema($field) {
+  // Make sure the installation API is available.
+  include_once DRUPAL_ROOT . '/includes/install.inc';
+  module_load_all_includes('install');
+  $schema = (array) module_invoke($field['module'], 'field_schema', $field);
+  $schema += array('columns' => array(), 'indexes' => array(), 'foreign keys' => array());
+  // Give other modules a chance to alter this definition.
+  // @see hook_field_schema_alter()
+  drupal_alter('field_schema', $schema, $field);
+  return $schema;
+}
+
 /**
  * Creates a field.
  *
@@ -130,9 +150,7 @@ function field_create_field($field) {
   $field['storage']['module'] = $storage_type['module'];
   $field['storage']['active'] = 1;
   // Collect storage information.
-  module_load_install($field['module']);
-  $schema = (array) module_invoke($field['module'], 'field_schema', $field);
-  $schema += array('columns' => array(), 'indexes' => array(), 'foreign keys' => array());
+  $schema = field_retrieve_schema($field);
   // 'columns' are hardcoded in the field type.
   $field['columns'] = $schema['columns'];
   // 'foreign keys' are hardcoded in the field type.
@@ -242,9 +260,7 @@ function field_update_field($field) {
 
   // Collect the new storage information, since what is in
   // $prior_field may no longer be right.
-  module_load_install($field['module']);
-  $schema = (array) module_invoke($field['module'], 'field_schema', $field);
-  $schema += array('columns' => array(), 'indexes' => array(), 'foreign keys' => array());
+  $schema = field_retrieve_schema($field);
   // 'columns' are hardcoded in the field type.
   $field['columns'] = $schema['columns'];
   // 'foreign keys' are hardcoded in the field type.
@@ -388,9 +404,7 @@ function field_read_fields($params = array(), $include_additional = array()) {
     module_invoke_all('field_read_field', $field);
 
     // Populate storage information.
-    module_load_install($field['module']);
-    $schema = (array) module_invoke($field['module'], 'field_schema', $field);
-    $schema += array('columns' => array(), 'indexes' => array());
+    $schema = field_retrieve_schema($field);
     $field['columns'] = $schema['columns'];
 
     $field_name = $field['field_name'];
@@ -469,6 +483,7 @@ function field_delete_field($field_name) {
  * @throws FieldException
  *
  * See: @link field Field API data structures @endlink.
+ * @see hook_field_schema_alter()
  */
 function field_create_instance($instance) {
   $field = field_read_field($instance['field_name']);
diff --git a/modules/field/tests/field.test b/modules/field/tests/field.test
index d53d9b706b..36ef49901e 100644
--- a/modules/field/tests/field.test
+++ b/modules/field/tests/field.test
@@ -2874,6 +2874,49 @@ class FieldCrudTestCase extends FieldTestCase {
   }
 }
 
+/**
+ * Tests that the field schema can be altered with hook_field_schema_alter().
+ */
+class FieldSchemaAlterTestCase extends FieldTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Field schema alteration tests',
+      'description' => 'Alter the schema for a given type of field.',
+      'group' => 'Field API',
+    );
+  }
+
+  function setUp() {
+    parent::setUp('field_test', 'field_test_schema_alter');
+  }
+
+  /**
+   * Tests a hook_field_schema_alter() implementation.
+   *
+   * @see field_test_schema_alter_field_schema_alter()
+   */
+  function testImageFieldSchemaAlter() {
+    $test_field = array(
+      'field_name' => drupal_strtolower($this->randomName()),
+      'type' => 'test_field',
+    );
+    field_create_field($test_field);
+    $test_field_name = $test_field['field_name'];
+    $test_field_instance_settings = array(
+      'field_name' => $test_field_name,
+      'entity_type' => 'test_entity',
+      'bundle' => 'test_bundle',
+      'deleted' => 0,
+    );
+    $test_field_instance = field_create_instance($test_field_instance_settings);
+
+    $table_name = _field_sql_storage_tablename($test_field_instance);
+    $schema = drupal_get_schema($table_name, TRUE);
+    $this->assertEqual('float', $schema['fields'][$test_field_name .'_value']['type']);
+    $this->assertTrue(db_field_exists($table_name, $test_field_name .'_additional_column'));
+  }
+}
+
 class FieldInstanceCrudTestCase extends FieldTestCase {
   protected $field;
   protected $instance_definition;
diff --git a/modules/field/tests/field_test_schema_alter.info b/modules/field/tests/field_test_schema_alter.info
new file mode 100644
index 0000000000..e955825194
--- /dev/null
+++ b/modules/field/tests/field_test_schema_alter.info
@@ -0,0 +1,6 @@
+name = "Field API Schema Alter Test"
+description = "Support module for the Field API schema alter tests."
+core = 7.x
+package = Testing
+version = VERSION
+hidden = TRUE
diff --git a/modules/field/tests/field_test_schema_alter.install b/modules/field/tests/field_test_schema_alter.install
new file mode 100644
index 0000000000..bfb28a553d
--- /dev/null
+++ b/modules/field/tests/field_test_schema_alter.install
@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * @file
+ * Install, update and uninstall functions for the field_test_schema_alter module.
+ */
+
+/**
+ * Implements hook_field_schema_alter().
+ */
+function field_test_schema_alter_field_schema_alter(&$schema, $field) {
+  if ($field['type'] == 'test_field') {
+    // Alter the field type.
+    $schema['columns']['value']['type'] = 'float';
+    // Add an additional column of data.
+    $schema['columns']['additional_column'] = array(
+      'description' => "Additional column added to image field table.",
+      'type' => 'varchar',
+      'length' => 128,
+      'not null' => FALSE,
+    );
+  }
+}
diff --git a/modules/field/tests/field_test_schema_alter.module b/modules/field/tests/field_test_schema_alter.module
new file mode 100644
index 0000000000..b3d9bbc7f3
--- /dev/null
+++ b/modules/field/tests/field_test_schema_alter.module
@@ -0,0 +1 @@
+<?php
