diff --git a/django/core/validators.py b/django/core/validators.py
index 796c57e..f07853e 100644
--- a/django/core/validators.py
+++ b/django/core/validators.py
@@ -114,12 +114,14 @@ class EmailValidator(object):
         if not self.user_regex.match(user_part):
             raise ValidationError(self.message, code=self.code)
 
-        if (not domain_part in self.domain_whitelist and
-                not self.domain_regex.match(domain_part)):
+        def domain_is_invalid(domain):
+            return not self.domain_regex.match(domain_part) or domain_part.endswith('.')
+
+        if domain_part not in self.domain_whitelist and domain_is_invalid(domain_part):
             # Try for possible IDN domain-part
             try:
                 domain_part = domain_part.encode('idna').decode('ascii')
-                if not self.domain_regex.match(domain_part):
+                if domain_is_invalid(domain_part):
                     raise ValidationError(self.message, code=self.code)
                 else:
                     return
diff --git a/tests/validators/tests.py b/tests/validators/tests.py
index 367bd43..e3f418e 100644
--- a/tests/validators/tests.py
+++ b/tests/validators/tests.py
@@ -56,6 +56,7 @@ TEST_DATA = (
     # Quoted-string format (CR not allowed)
     (validate_email, '"\\\011"@here.com', None),
     (validate_email, '"\\\012"@here.com', ValidationError),
+    (validate_email, 'trailingdot@shouldfail.com.', ValidationError),
 
     (validate_slug, 'slug-ok', None),
     (validate_slug, 'longer-slug-still-ok', None),
