diff --git a/server/src/main/java/org/elasticsearch/index/mapper/GeoShapeIndexer.java b/server/src/main/java/org/elasticsearch/index/mapper/GeoShapeIndexer.java
index 9a103471a21a3..4dc368612c9aa 100644
--- a/server/src/main/java/org/elasticsearch/index/mapper/GeoShapeIndexer.java
+++ b/server/src/main/java/org/elasticsearch/index/mapper/GeoShapeIndexer.java
@@ -26,6 +26,7 @@
 import org.elasticsearch.common.geo.GeoPolygonDecomposer;
 import org.elasticsearch.common.geo.GeoShapeUtils;
 import org.elasticsearch.common.geo.GeoShapeType;
+import org.elasticsearch.common.geo.GeoUtils;
 import org.elasticsearch.geometry.Circle;
 import org.elasticsearch.geometry.Geometry;
 import org.elasticsearch.geometry.GeometryCollection;
@@ -261,7 +262,15 @@ public Void visit(Polygon polygon) {
 
         @Override
         public Void visit(Rectangle r) {
-            addFields(LatLonShape.createIndexableFields(name, GeoShapeUtils.toLucenePolygon(r)));
+            if (r.getMinLon() > r.getMaxLon()) {
+                Rectangle left = new Rectangle(r.getMinLon(), GeoUtils.MAX_LON, r.getMaxLat(), r.getMinLat());
+                addFields(LatLonShape.createIndexableFields(name, GeoShapeUtils.toLucenePolygon(left)));
+                Rectangle right = new Rectangle(GeoUtils.MIN_LON, r.getMaxLon(), r.getMaxLat(), r.getMinLat());
+                addFields(LatLonShape.createIndexableFields(name, GeoShapeUtils.toLucenePolygon(right)));
+
+            } else {
+                addFields(LatLonShape.createIndexableFields(name, GeoShapeUtils.toLucenePolygon(r)));
+            }
             return null;
         }
 
diff --git a/server/src/test/java/org/elasticsearch/common/geo/GeometryIndexerTests.java b/server/src/test/java/org/elasticsearch/common/geo/GeometryIndexerTests.java
index f5828aad13ee1..ddee41639cd3c 100644
--- a/server/src/test/java/org/elasticsearch/common/geo/GeometryIndexerTests.java
+++ b/server/src/test/java/org/elasticsearch/common/geo/GeometryIndexerTests.java
@@ -19,6 +19,7 @@
 
 package org.elasticsearch.common.geo;
 
+import org.apache.lucene.index.IndexableField;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentFactory;
 import org.elasticsearch.common.xcontent.XContentParser;
@@ -33,6 +34,7 @@
 import org.elasticsearch.geometry.MultiPolygon;
 import org.elasticsearch.geometry.Point;
 import org.elasticsearch.geometry.Polygon;
+import org.elasticsearch.geometry.Rectangle;
 import org.elasticsearch.index.mapper.GeoShapeIndexer;
 import org.elasticsearch.test.ESTestCase;
 import java.io.IOException;
@@ -292,6 +294,24 @@ public void testMultiPoint() {
         assertEquals(indexed, indexer.prepareForIndexing(multiPoint));
     }
 
+    public void testRectangle() {
+        Rectangle indexed = new Rectangle(-179, -178, 10, -10);
+        Geometry processed = indexer.prepareForIndexing(indexed);
+        assertEquals(indexed, processed);
+
+        // a rectangle is broken into two triangles
+        List<IndexableField> fields = indexer.indexShape(null, indexed);
+        assertEquals(fields.size(), 2);
+
+        indexed = new Rectangle(179, -179, 10, -10);
+        processed = indexer.prepareForIndexing(indexed);
+        assertEquals(indexed, processed);
+
+        // a rectangle crossing the dateline is broken into 4 triangles
+        fields = indexer.indexShape(null, indexed);
+        assertEquals(fields.size(), 4);
+    }
+
     public void testPolygon() {
         Polygon polygon = new Polygon(new LinearRing(new double[]{160, 200, 200, 160, 160}, new double[]{10, 10, 20, 20, 10}));
         Geometry indexed = new MultiPolygon(Arrays.asList(
diff --git a/server/src/test/java/org/elasticsearch/search/geo/GeoShapeQueryTests.java b/server/src/test/java/org/elasticsearch/search/geo/GeoShapeQueryTests.java
index 032c6d68766be..eca23aba9eab0 100644
--- a/server/src/test/java/org/elasticsearch/search/geo/GeoShapeQueryTests.java
+++ b/server/src/test/java/org/elasticsearch/search/geo/GeoShapeQueryTests.java
@@ -791,4 +791,24 @@ public void testDistanceQuery() throws Exception {
             .get();
         assertEquals(0, response.getHits().getTotalHits().value);
     }
+
+    public void testIndexRectangleSpanningDateLine() throws Exception {
+        String mapping = Strings.toString(createRandomMapping());
+
+        client().admin().indices().prepareCreate("test").setMapping(mapping).get();
+        ensureGreen();
+
+        EnvelopeBuilder envelopeBuilder = new EnvelopeBuilder(new Coordinate(178, 10), new Coordinate(-178, -10));
+
+        XContentBuilder docSource = envelopeBuilder.toXContent(jsonBuilder().startObject().field("geo"), null).endObject();
+        client().prepareIndex("test").setId("1").setSource(docSource).setRefreshPolicy(IMMEDIATE).get();
+
+        ShapeBuilder filterShape = new PointBuilder(179, 0);
+
+        GeoShapeQueryBuilder geoShapeQueryBuilder = QueryBuilders.geoShapeQuery("geo", filterShape);
+        geoShapeQueryBuilder.relation(ShapeRelation.INTERSECTS);
+        SearchResponse result = client().prepareSearch("test").setQuery(geoShapeQueryBuilder).get();
+        assertSearchResponse(result);
+        assertHitCount(result, 1);
+    }
 }