diff --git a/django/forms/widgets.py b/django/forms/widgets.py
index 6b1be37..260b9a5 100644
--- a/django/forms/widgets.py
+++ b/django/forms/widgets.py
@@ -528,7 +528,7 @@ class CheckboxInput(Widget):
         values =  {'true': True, 'false': False}
         if isinstance(value, six.string_types):
             value = values.get(value.lower(), value)
-        return value
+        return bool(value)
 
     def _has_changed(self, initial, data):
         # Sometimes data or initial could be None or '' which should be the
diff --git a/tests/regressiontests/forms/tests/forms.py b/tests/regressiontests/forms/tests/forms.py
index a8a28ba..1c83ed0 100644
--- a/tests/regressiontests/forms/tests/forms.py
+++ b/tests/regressiontests/forms/tests/forms.py
@@ -269,6 +269,11 @@ class FormsTestCase(TestCase):
         f = SignupForm({'email': 'test@example.com', 'get_spam': 'false'}, auto_id=False)
         self.assertHTMLEqual(str(f['get_spam']), '<input type="checkbox" name="get_spam" />')
 
+        # A value of '0' should be interpreted as a True value (#16820)
+        f = SignupForm({'email': 'test@example.com', 'get_spam': '0'})
+        self.assertTrue(f.is_valid())
+        self.assertTrue(f.cleaned_data.get('get_spam'))
+
     def test_widget_output(self):
         # Any Field can have a Widget class passed to its constructor:
         class ContactForm(Form):
diff --git a/tests/regressiontests/forms/tests/widgets.py b/tests/regressiontests/forms/tests/widgets.py
index 3ea42cf..9924f3b 100644
--- a/tests/regressiontests/forms/tests/widgets.py
+++ b/tests/regressiontests/forms/tests/widgets.py
@@ -228,6 +228,10 @@ class FormsWidgetTestCase(TestCase):
         # checkboxes).
         self.assertFalse(w.value_from_datadict({}, {}, 'testing'))
 
+        value = w.value_from_datadict({'testing': '0'}, {}, 'testing')
+        self.assertTrue(isinstance(value, bool))
+        self.assertTrue(value)
+
         self.assertFalse(w._has_changed(None, None))
         self.assertFalse(w._has_changed(None, ''))
         self.assertFalse(w._has_changed('', None))
