diff --git a/lib/geocoder/lookup.rb b/lib/geocoder/lookup.rb
index 1ec88606595435af439f5dd6361b02573df6dbbf..3a6e7a782b8bba25bdf4f4516dc99d4bd3f9a3f8 100644
--- a/lib/geocoder/lookup.rb
+++ b/lib/geocoder/lookup.rb
@@ -52,6 +52,7 @@ module Geocoder
       [
         :baidu_ip,
         :freegeoip,
+        :geolite2,
         :maxmind,
         :maxmind_local,
         :telize,
diff --git a/lib/geocoder/lookups/geolite2.rb b/lib/geocoder/lookups/geolite2.rb
new file mode 100644
index 0000000000000000000000000000000000000000..83bb05d4b1312d89ea8d28af8f43a22017a15324
--- /dev/null
+++ b/lib/geocoder/lookups/geolite2.rb
@@ -0,0 +1,39 @@
+require 'ipaddr'
+require 'geocoder/lookups/base'
+require 'geocoder/results/geolite2'
+
+module Geocoder
+  module Lookup
+    class Geolite2 < Base
+      def initialize
+        unless configuration[:file].nil?
+          begin
+            gem_name = 'hive_geoip2'
+            require gem_name
+          rescue LoadError
+            raise "Could not load maxminddb dependency. To use MaxMind2 Local \
+            lookup you must add the #{gem_name} gem to your Gemfile or \
+            have it installed in your system."
+          end
+        end
+        super
+      end
+
+      def name
+        'GeoLite2'
+      end
+
+      def required_api_key_parts
+        []
+      end
+
+      private
+
+      def results(query)
+        return [] unless configuration[:file]
+        result = Hive::GeoIP2.lookup(query.to_s, configuration[:file].to_s)
+        result.nil? ? [] : [result]
+      end
+    end
+  end
+end
diff --git a/lib/geocoder/results/geolite2.rb b/lib/geocoder/results/geolite2.rb
new file mode 100644
index 0000000000000000000000000000000000000000..94dd5db3d9e98ac7cdc94956c916894d8abcc164
--- /dev/null
+++ b/lib/geocoder/results/geolite2.rb
@@ -0,0 +1,64 @@
+require 'geocoder/results/base'
+
+module Geocoder
+  module Result
+    class Geolite2 < Base
+      def address(format = :full)
+        s = state.to_s == '' ? '' : ", #{state}"
+        "#{city}#{s} #{postal_code}, #{country}".sub(/^[ ,]*/, '')
+      end
+
+      def coordinates
+        [latitude, longitude]
+      end
+
+      def latitude
+        return 0.0 unless @data['location']
+        @data['location']['latitude'].to_f
+      end
+
+      def longitude
+        return 0.0 unless @data['location']
+        @data['location']['longitude'].to_f
+      end
+
+      def city
+        return '' unless @data['city']
+        @data['city']['names']['en']
+      end
+
+      def state
+        return '' unless @data['subdivisions']
+        @data['subdivisions'][0]['names']['en']
+      end
+
+      def state_code
+        return '' unless @data['subdivisions']
+        @data['subdivisions'][0]['iso_code']
+      end
+
+      def country
+        @data['country']['names']['en']
+      end
+
+      def country_code
+        @data['country']['iso_code']
+      end
+
+      def postal_code
+        return '' unless @data['postal']
+        @data['postal']['code']
+      end
+
+      def self.response_attributes
+        %w[ip]
+      end
+
+      response_attributes.each do |a|
+        define_method a do
+          @data[a]
+        end
+      end
+    end
+  end
+end