diff --git a/django/db/backends/schema.py b/django/db/backends/schema.py
index b3f58b48d6..d0c4639d7f 100644
--- a/django/db/backends/schema.py
+++ b/django/db/backends/schema.py
@@ -167,6 +167,9 @@ class BaseDatabaseSchemaEditor(object):
         # If it's a callable, call it
         if callable(default):
             default = default()
+        # Run it through the field's get_db_prep_save method so we can send it
+        # to the database.
+        default = field.get_db_prep_save(default, self.connection)
         return default
 
     def quote_value(self, value):
diff --git a/django/db/backends/sqlite3/schema.py b/django/db/backends/sqlite3/schema.py
index a8417d4f66..005d4b13c8 100644
--- a/django/db/backends/sqlite3/schema.py
+++ b/django/db/backends/sqlite3/schema.py
@@ -1,3 +1,4 @@
+from decimal import Decimal
 from django.utils import six
 from django.apps.registry import Apps
 from django.db.backends.schema import BaseDatabaseSchemaEditor
@@ -19,6 +20,8 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
         # Manual emulation of SQLite parameter quoting
         if isinstance(value, type(True)):
             return str(int(value))
+        elif isinstance(value, (Decimal, float)):
+            return str(value)
         elif isinstance(value, six.integer_types):
             return str(value)
         elif isinstance(value, six.string_types):
@@ -26,7 +29,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
         elif value is None:
             return "NULL"
         else:
-            raise ValueError("Cannot quote parameter value %r" % value)
+            raise ValueError("Cannot quote parameter value %r of type %s" % (value, type(value)))
 
     def _remake_table(self, model, create_fields=[], delete_fields=[], alter_fields=[], rename_fields=[], override_uniques=None):
         """
@@ -52,7 +55,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
             # If there's a default, insert it into the copy map
             if field.has_default():
                 mapping[field.column] = self.quote_value(
-                    field.get_default()
+                    self.effective_default(field)
                 )
         # Add in any altered fields
         for (old_field, new_field) in alter_fields:
diff --git a/tests/schema/tests.py b/tests/schema/tests.py
index 0ab5bb0363..55b2ee5ce3 100644
--- a/tests/schema/tests.py
+++ b/tests/schema/tests.py
@@ -231,6 +231,40 @@ class SchemaTests(TransactionTestCase):
         else:
             self.assertEqual(field_type, 'BooleanField')
 
+    def test_add_field_default_transform(self):
+        """
+        Tests adding fields to models with a default that is not directly
+        valid in the database (#22581)
+        """
+        class TestTransformField(IntegerField):
+            # Weird field that saves the count of items in its value
+            def get_default(self):
+                return self.default
+            def get_prep_value(self, value):
+                if value is None:
+                    return 0
+                return len(value)
+        # Create the table
+        with connection.schema_editor() as editor:
+            editor.create_model(Author)
+        # Add some rows of data
+        Author.objects.create(name="Andrew", height=30)
+        Author.objects.create(name="Andrea")
+        # Add the field with a default it needs to cast (to string in this case)
+        new_field = TestTransformField(default={1:2})
+        new_field.set_attributes_from_name("thing")
+        with connection.schema_editor() as editor:
+            editor.add_field(
+                Author,
+                new_field,
+            )
+        # Ensure the field is there
+        columns = self.column_classes(Author)
+        field_type, field_info = columns['thing']
+        self.assertEqual(field_type, 'IntegerField')
+        # Make sure the values were transformed correctly
+        self.assertEqual(Author.objects.extra(where=["thing = 1"]).count(), 2)
+
     def test_alter(self):
         """
         Tests simple altering of fields