diff --git a/assets/tiled_image_layers.tmx b/assets/tiled_image_layers.tmx
new file mode 100644
index 0000000000000000000000000000000000000000..e7dc7f3fc99c6732b44e214d9208e2111c070a1a
--- /dev/null
+++ b/assets/tiled_image_layers.tmx
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<map version="1.0" tiledversion="1.0.3" orientation="orthogonal" renderorder="right-down" width="100" height="100" tilewidth="32" tileheight="32" nextobjectid="1">
+ <tileset firstgid="1" name="tilesheet" tilewidth="32" tileheight="32" tilecount="84" columns="14">
+  <image source="tilesheet.png" width="448" height="192"/>
+ </tileset>
+ <imagelayer name="Image Layer 1"/>
+ <imagelayer name="Image Layer 2">
+  <image source="tilesheet.png" width="448" height="192"/>
+ </imagelayer>
+</map>
diff --git a/src/lib.rs b/src/lib.rs
index 5f91dcb7336b9cb587f02adb25be4b35b7799c62..f48223d7feb984efa721f8230bfc4357f524a606 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -228,6 +228,7 @@ pub struct Map {
     pub tile_height: u32,
     pub tilesets: Vec<Tileset>,
     pub layers: Vec<Layer>,
+    pub image_layers: Vec<ImageLayer>,
     pub object_groups: Vec<ObjectGroup>,
     pub properties: Properties,
     pub background_colour: Option<Colour>,
@@ -248,6 +249,7 @@ impl Map {
 
         let mut tilesets = Vec::new();
         let mut layers = Vec::new();
+        let mut image_layers = Vec::new();
         let mut properties = HashMap::new();
         let mut object_groups = Vec::new();
         parse_tag!(parser, "map",
@@ -259,6 +261,10 @@ impl Map {
                         layers.push(try!(Layer::new(parser, attrs, w)));
                         Ok(())
                    },
+                   "imagelayer" => |attrs| {
+                        image_layers.push(try!(ImageLayer::new(parser, attrs)));
+                        Ok(())
+                   },
                    "properties" => |_| {
                         properties = try!(parse_properties(parser));
                         Ok(())
@@ -270,8 +276,11 @@ impl Map {
         Ok(Map {version: v, orientation: o,
                 width: w, height: h,
                 tile_width: tw, tile_height: th,
-                tilesets: tilesets, layers: layers, object_groups: object_groups,
-                properties: properties,
+                tilesets,
+                layers,
+                image_layers,
+                object_groups,
+                properties,
                 background_colour: c,})
     }
 
@@ -520,6 +529,53 @@ impl Layer {
     }
 }
 
+#[derive(Debug, PartialEq, Clone)]
+pub struct ImageLayer {
+    pub name: String,
+    pub opacity: f32,
+    pub visible: bool,
+    pub offset_x: f32,
+    pub offset_y: f32,
+    pub image: Option<Image>,
+    pub properties: Properties
+}
+
+impl ImageLayer {
+    fn new<R: Read>(parser: &mut EventReader<R>, attrs: Vec<OwnedAttribute>)
+                    -> Result<ImageLayer, TiledError> {
+        let ((o, v, ox, oy), n) = get_attrs!(
+            attrs,
+            optionals: [("opacity", opacity, |v:String| v.parse().ok()),
+                        ("visible", visible, |v:String| v.parse().ok().map(|x:i32| x == 1)),
+                        ("offset_x", offset_x, |v:String| v.parse().ok()),
+                        ("offset_y", offset_y, |v:String| v.parse().ok())],
+            required: [("name", name, |v| Some(v))],
+            TiledError::MalformedAttributes("layer must have a name".to_string()));
+        let mut properties = HashMap::new();
+        let mut image: Option<Image> = None;
+        parse_tag!(parser, "imagelayer",
+                   "image" => |attrs| {
+                       image = Some(Image::new(parser, attrs)?);
+                       Ok(())
+                   },
+                   "properties" => |_| {
+                       properties = parse_properties(parser)?;
+                       Ok(())
+                   });
+        Ok(ImageLayer {
+            name: n,
+            opacity: o.unwrap_or(1.0),
+            visible: v.unwrap_or(true),
+            offset_x: ox.unwrap_or(0.0),
+            offset_y: oy.unwrap_or(0.0),
+            image,
+            properties,
+        })
+    }
+}
+
+
+
 #[derive(Debug, PartialEq, Clone)]
 pub struct ObjectGroup {
     pub name: String,
diff --git a/tests/lib.rs b/tests/lib.rs
index 7da63c8fe49d2418009707e793d083adaf35d7b6..8e2c2c77bd8c94e41dad0700362ac844778062c0 100644
--- a/tests/lib.rs
+++ b/tests/lib.rs
@@ -38,6 +38,26 @@ fn test_just_tileset() {
     assert_eq!(r.tilesets[0], t);
 }
 
+#[test]
+fn test_image_layers() {
+    let r = read_from_file(&Path::new("assets/tiled_image_layers.tmx")).unwrap();
+    assert_eq!(r.image_layers.len(), 2);
+    {
+        let first = &r.image_layers[0];
+        assert_eq!(first.name, "Image Layer 1");
+        assert!(first.image.is_none(), "{}'s image should be None", first.name);
+    }
+    {
+        let second = &r.image_layers[1];
+        assert_eq!(second.name, "Image Layer 2");
+        let image = second.image.as_ref().expect(&format!("{}'s image shouldn't be None", second.name));
+        assert_eq!(image.source, "tilesheet.png");
+        assert_eq!(image.width, 448);
+        assert_eq!(image.height, 192);
+    }
+}
+
+
 #[test]
 fn test_tile_property() {
     let r = read_from_file(&Path::new("assets/tiled_base64.tmx")).unwrap();