diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 61fd2be..0bacdc8 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -1045,11 +1045,29 @@ class Query(object):
         if not parts:
             raise FieldError("Cannot parse keyword query %r" % arg)
 
-        # Work out the lookup type and remove it from 'parts', if necessary.
-        if len(parts) == 1 or parts[-1] not in self.query_terms:
-            lookup_type = 'exact'
-        else:
-            lookup_type = parts.pop()
+#        if parts[-1] == 'year':
+#            import pdb; pdb.set_trace()
+
+        # Work out the lookup type and remove it from the end of 'parts',
+        # if necessary.
+        lookup_type = 'exact' # Default lookup type
+        num_parts = len(parts)
+        if num_parts > 1 and arg not in self.aggregates:
+            # Traverse the lookup query to distinguish related fields from
+            # lookup types.
+            try:
+                lookup_model = self.model
+                for counter, field_name in enumerate(parts):
+                    lookup_field = lookup_model._meta.get_field(field_name)
+                    if (counter + 1) < num_parts:
+                        # Unless we're at the end of the list of lookups, let's
+                        # attempt to continue traversing relations.
+                        lookup_model = lookup_field.rel.to
+            except (FieldDoesNotExist, AttributeError):
+                # The traversing didn't reach the end because at least one of
+                # the lookups wasn't a field.
+                if parts[-1] in self.query_terms:
+                    lookup_type = parts.pop()
 
         # By default, this is a WHERE clause. If an aggregate is referenced
         # in the value, the filter will be promoted to a HAVING
diff --git a/tests/modeltests/lookup/models.py b/tests/modeltests/lookup/models.py
index 82434bb..dbd52e3 100644
--- a/tests/modeltests/lookup/models.py
+++ b/tests/modeltests/lookup/models.py
@@ -26,3 +26,25 @@ class Tag(models.Model):
     name = models.CharField(max_length=100)
     class Meta:
         ordering = ('name', )
+
+class Season(models.Model):
+    year = models.PositiveSmallIntegerField()
+    gt = models.IntegerField(null=True, blank=True)
+
+    def __unicode__(self):
+        return unicode(self.year)
+
+class Game(models.Model):
+    season = models.ForeignKey(Season, related_name='games')
+    home = models.CharField(max_length=100)
+    away = models.CharField(max_length=100)
+
+    def __unicode__(self):
+        return u"%s at %s" % (self.away, self.home)
+
+class Player(models.Model):
+    name = models.CharField(max_length=100)
+    games = models.ManyToManyField(Game, related_name='players')
+
+    def __unicode__(self):
+        return self.name
\ No newline at end of file
diff --git a/tests/modeltests/lookup/tests.py b/tests/modeltests/lookup/tests.py
index 33eeae7..6e4d98e 100644
--- a/tests/modeltests/lookup/tests.py
+++ b/tests/modeltests/lookup/tests.py
@@ -1,8 +1,10 @@
 from datetime import datetime
 from operator import attrgetter
+
 from django.core.exceptions import FieldError
 from django.test import TestCase, skipUnlessDBFeature
-from models import Author, Article, Tag
+
+from models import Author, Article, Tag, Game, Season, Player
 
 
 class LookupTests(TestCase):
@@ -243,7 +245,7 @@ class LookupTests(TestCase):
         self.assertQuerysetEqual(Article.objects.filter(id=self.a5.id).values(),
             [{
                 'id': self.a5.id,
-                'author_id': self.au2.id, 
+                'author_id': self.au2.id,
                 'headline': 'Article 5',
                 'pub_date': datetime(2005, 8, 1, 9, 0)
             }], transform=identity)
@@ -606,3 +608,70 @@ class LookupTests(TestCase):
         a16.save()
         self.assertQuerysetEqual(Article.objects.filter(headline__regex=r'b(.).*b\1'),
             ['<Article: barfoobaz>', '<Article: bazbaRFOO>', '<Article: foobarbaz>'])
+
+class LookupCollisionTests(TestCase):
+
+    def setUp(self):
+        # Here we're using 'gt' as a code number for the year, e.g. 111=>2009.
+        season_2009 = Season.objects.create(year=2009, gt=111)
+        season_2009.games.create(home="Houston Astros", away="St. Louis Cardinals")
+        season_2010 = Season.objects.create(year=2010, gt=222)
+        season_2010.games.create(home="Houston Astros", away="Chicago Cubs")
+        season_2010.games.create(home="Houston Astros", away="Milwaukee Brewers")
+        season_2010.games.create(home="Houston Astros", away="St. Louis Cardinals")
+        season_2011 = Season.objects.create(year=2011, gt=333)
+        season_2011.games.create(home="Houston Astros", away="St. Louis Cardinals")
+        season_2011.games.create(home="Houston Astros", away="Milwaukee Brewers")
+        hunter_pence = Player.objects.create(name="Hunter Pence")
+        hunter_pence.games = Game.objects.filter(season__year__in=[2009, 2010])
+        pudge = Player.objects.create(name="Ivan Rodriquez")
+        pudge.games = Game.objects.filter(season__year=2009)
+        pedro_feliz = Player.objects.create(name="Pedro Feliz")
+        pedro_feliz.games = Game.objects.filter(season__year__in=[2011])
+        johnson = Player.objects.create(name="Johnson")
+        johnson.games = Game.objects.filter(season__year__in=[2011])
+
+    def test_lookup_collision(self):
+        """
+        Ensure that genuine field names don't collide with built-in lookup
+        types ('year', 'gt', 'range', 'in' etc.).
+        Refs #11670.
+        """
+        # Games in 2010
+        self.assertEqual(Game.objects.filter(season__year=2010).count(), 3)
+        self.assertEqual(Game.objects.filter(season__year__exact=2010).count(), 3)
+        self.assertEqual(Game.objects.filter(season__gt=222).count(), 3)
+        self.assertEqual(Game.objects.filter(season__gt__exact=222).count(), 3)
+
+        # Games in 2011
+        self.assertEqual(Game.objects.filter(season__year=2011).count(), 2)
+        self.assertEqual(Game.objects.filter(season__year__exact=2011).count(), 2)
+        self.assertEqual(Game.objects.filter(season__gt=333).count(), 2)
+        self.assertEqual(Game.objects.filter(season__gt__exact=333).count(), 2)
+        self.assertEqual(Game.objects.filter(season__year__gt=2010).count(), 2)
+        self.assertEqual(Game.objects.filter(season__gt__gt=222).count(), 2)
+
+        # Games played in 2010 and 2011
+        self.assertEqual(Game.objects.filter(season__year__in=[2010, 2011]).count(), 5)
+        self.assertEqual(Game.objects.filter(season__year__gt=2009).count(), 5)
+        self.assertEqual(Game.objects.filter(season__gt__in=[222, 333]).count(), 5)
+        self.assertEqual(Game.objects.filter(season__gt__gt=111).count(), 5)
+
+        # Players who played in 2009
+        self.assertEqual(Player.objects.filter(games__season__year=2009).distinct().count(), 2)
+        self.assertEqual(Player.objects.filter(games__season__year__exact=2009).distinct().count(), 2)
+        self.assertEqual(Player.objects.filter(games__season__gt=111).distinct().count(), 2)
+        self.assertEqual(Player.objects.filter(games__season__gt__exact=111).distinct().count(), 2)
+
+        # Players who played in 2010
+        self.assertEqual(Player.objects.filter(games__season__year=2010).distinct().count(), 1)
+        self.assertEqual(Player.objects.filter(games__season__year__exact=2010).distinct().count(), 1)
+        self.assertEqual(Player.objects.filter(games__season__gt=222).distinct().count(), 1)
+        self.assertEqual(Player.objects.filter(games__season__gt__exact=222).distinct().count(), 1)
+
+        # Players who played in 2011
+        self.assertEqual(Player.objects.filter(games__season__year=2011).distinct().count(), 2)
+        self.assertEqual(Player.objects.filter(games__season__year__exact=2011).distinct().count(), 2)
+        self.assertEqual(Player.objects.filter(games__season__gt=333).distinct().count(), 2)
+        self.assertEqual(Player.objects.filter(games__season__year__gt=2010).distinct().count(), 2)
+        self.assertEqual(Player.objects.filter(games__season__gt__gt=222).distinct().count(), 2)
