diff --git a/lib/geocoder/lookup.rb b/lib/geocoder/lookup.rb
index e8d6b96b0cc3dc48af8533624399d1d721712f9b..2bb2d34b88f9dd366bb68d407692afe01bfd5c7a 100644
--- a/lib/geocoder/lookup.rb
+++ b/lib/geocoder/lookup.rb
@@ -33,6 +33,7 @@ module Geocoder
         :nominatim,
         :mapquest,
         :ovi,
+        :baidu,
         :test
       ]
     end
diff --git a/lib/geocoder/lookups/baidu.rb b/lib/geocoder/lookups/baidu.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4bd80f21c30e4ffab441822e69e4aa038a2472d5
--- /dev/null
+++ b/lib/geocoder/lookups/baidu.rb
@@ -0,0 +1,54 @@
+require 'geocoder/lookups/base'
+require "geocoder/results/baidu"
+
+module Geocoder::Lookup
+  class Baidu < Base
+
+    def name
+      "Baidu"
+    end
+
+    def required_api_key_parts
+      ["key"]
+    end
+
+    def query_url(query)
+      "http://api.map.baidu.com/geocoder/v2/?" + url_query_string(query)
+    end
+
+    private # ---------------------------------------------------------------
+
+    def results(query, reverse = false)
+      return [] unless doc = fetch_data(query)
+      case doc['status']; when 0
+        return [doc['result']]
+      when 1, 3, 4
+        raise_error(Geocoder::Error, messages) ||
+          warn("Baidu Geocoding API error: server error.")
+      when 2
+        raise_error(Geocoder::InvalidRequest, messages) ||
+          warn("Baidu Geocoding API error: invalid request.")
+      when 5
+        raise_error(Geocoder::InvalidApiKey, messages) ||
+          warn("Baidu Geocoding API error: invalid api key.")
+      when 101, 102, 200..299
+        raise_error(Geocoder::RequestDenied) ||
+          warn("Baidu Geocoding API error: request denied.")
+      when 300..399
+        raise_error(Geocoder::OverQueryLimitError) ||
+          warn("Baidu Geocoding API error: over query limit.")
+      end
+      return []
+    end
+
+    def query_url_params(query)
+      {
+        (query.reverse_geocode? ? :location : :address) => query.sanitized_text,
+        :ak => configuration.api_key,
+        :output => "json"
+      }
+    end
+
+  end
+end
+
diff --git a/lib/geocoder/results/baidu.rb b/lib/geocoder/results/baidu.rb
new file mode 100644
index 0000000000000000000000000000000000000000..27adbde1ccbd2460065a22e5ad6735290643a6f8
--- /dev/null
+++ b/lib/geocoder/results/baidu.rb
@@ -0,0 +1,63 @@
+require 'geocoder/results/base'
+
+module Geocoder::Result
+  class Baidu < Base
+
+    def coordinates
+      ['lat', 'lng'].map{ |i| @data['location'][i] }
+    end
+
+    def address
+      @data['formatted_address']
+    end
+
+    def state
+      province
+    end
+    
+    def province
+      @data['addressComponent']['province']
+    end
+
+    def city
+      @data['addressComponent']['city']
+    end
+
+    def district
+      @data['addressComponent']['district']
+    end
+
+    def street
+      @data['addressComponent']['street']
+    end
+
+    def street_number
+      @data['addressComponent']['street_number']
+    end
+
+    def formatted_address
+      @data['formatted_address']
+    end
+
+    def address_components
+      @data['addressComponent']
+    end
+
+    ##
+    # Get address components of a given type. Valid types are defined in
+    # Baidu's Geocoding API documentation and include (among others):
+    #
+    #   :business
+    #   :cityCode
+    #
+    def self.response_attributes
+      %w[business cityCode]
+    end
+
+    response_attributes.each do |a|
+      define_method a do
+        @data[a]
+      end
+    end
+  end
+end