diff --git a/examples/select-features.html b/examples/select-features.html
new file mode 100644
index 0000000000..8e34f3422b
--- /dev/null
+++ b/examples/select-features.html
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+ Select featuers example
+
+
+
+
+
+
+
+
+
+
+
+
+
Select features example
+
Example of using the Select control.
+
+
SelectFeature, vector
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/select-features.js b/examples/select-features.js
new file mode 100644
index 0000000000..cb13f361e6
--- /dev/null
+++ b/examples/select-features.js
@@ -0,0 +1,48 @@
+goog.require('ol.Map');
+goog.require('ol.RendererHint');
+goog.require('ol.View2D');
+goog.require('ol.control.Select');
+goog.require('ol.control.defaults');
+goog.require('ol.layer.TileLayer');
+goog.require('ol.layer.Vector');
+goog.require('ol.parser.ogc.GML_v3');
+goog.require('ol.source.MapQuestOpenAerial');
+goog.require('ol.source.Vector');
+goog.require('ol.style.Polygon');
+goog.require('ol.style.Rule');
+goog.require('ol.style.Style');
+
+var raster = new ol.layer.TileLayer({
+ source: new ol.source.MapQuestOpenAerial()
+});
+
+var vector = new ol.layer.Vector({
+ source: new ol.source.Vector({
+ parser: new ol.parser.ogc.GML_v3(),
+ url: 'data/gml/topp-states-wfs.xml'
+ }),
+ style: new ol.style.Style({rules: [
+ new ol.style.Rule({
+ symbolizers: [
+ new ol.style.Polygon({
+ strokeColor: '#bada55'
+ })
+ ]
+ })
+ ]})
+});
+
+var selectControl = new ol.control.Select({layers: [vector]});
+
+var map = new ol.Map({
+ controls: ol.control.defaults({}, [selectControl]),
+ layers: [raster, vector],
+ renderer: ol.RendererHint.CANVAS,
+ target: 'map',
+ view: new ol.View2D({
+ center: [-10997171.194994785, 5206335.565590534],
+ zoom: 4
+ })
+});
+
+selectControl.activate();
diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc
index 973fd47471..04cda33390 100644
--- a/src/objectliterals.jsdoc
+++ b/src/objectliterals.jsdoc
@@ -201,6 +201,15 @@
* Default is '' (empty string).
*/
+/**
+ * @typedef {Object} ol.control.SelectOptions
+ * @property {string|undefined} className CSS class name. Default is 'ol-select'.
+ * @property {Element|undefined} element Element.
+ * @property {Array.|undefined} layers Layers to select features on.
+ * @property {ol.Map|undefined} map Map.
+ * @property {Element|undefined} target Target.
+ */
+
/**
* @typedef {Object} ol.control.ScaleLineOptions
* @property {string|undefined} className CSS Class name. Default is 'ol-scale-line'.
diff --git a/src/ol/control/selectcontrol.js b/src/ol/control/selectcontrol.js
new file mode 100644
index 0000000000..20c5b34933
--- /dev/null
+++ b/src/ol/control/selectcontrol.js
@@ -0,0 +1,106 @@
+goog.provide('ol.control.Select');
+
+goog.require('goog.array');
+goog.require('goog.dom');
+goog.require('goog.dom.TagName');
+goog.require('goog.dom.classes');
+goog.require('goog.events');
+goog.require('goog.events.EventType');
+goog.require('ol.MapBrowserEvent.EventType');
+goog.require('ol.control.Control');
+goog.require('ol.css');
+
+
+
+/**
+ * @constructor
+ * @extends {ol.control.Control}
+ * @param {ol.control.SelectOptions=} opt_options Options.
+ */
+ol.control.Select = function(opt_options) {
+ var options = goog.isDef(opt_options) ? opt_options : {};
+
+ this.layers_ = options.layers;
+
+ var className = goog.isDef(options.className) ? options.className :
+ 'ol-select';
+
+ var element = goog.dom.createDom(goog.dom.TagName.DIV, {
+ 'class': className + ' ' + ol.css.CLASS_UNSELECTABLE
+ });
+ var button = goog.dom.createDom(goog.dom.TagName.A, {
+ 'href': '#Select'
+ });
+ goog.dom.appendChild(element, button);
+
+ goog.events.listen(element, [
+ goog.events.EventType.TOUCHEND,
+ goog.events.EventType.CLICK
+ ], this.toggleActive_, false, this);
+
+ goog.base(this, {
+ element: element,
+ map: options.map,
+ target: options.target
+ });
+};
+goog.inherits(ol.control.Select, ol.control.Control);
+
+
+/**
+ * @param {goog.events.BrowserEvent} browserEvent Browser event.
+ * @private
+ */
+ol.control.Select.prototype.toggleActive_ = function(browserEvent) {
+ // prevent #Select anchor from getting appended to the url
+ browserEvent.preventDefault();
+ if (this.active_) {
+ this.deactivate();
+ } else {
+ this.activate();
+ }
+};
+
+
+/**
+ * Activate the control.
+ */
+ol.control.Select.prototype.activate = function() {
+ goog.dom.classes.add(this.element, 'active');
+ // TODO: Add box selection
+ this.listenerKeys.push(
+ goog.events.listen(this.getMap(), ol.MapBrowserEvent.EventType.CLICK,
+ this.handleClick, true, this));
+};
+
+
+/**
+ * Dectivate the control.
+ */
+ol.control.Select.prototype.deactivate = function() {
+ if (!goog.array.isEmpty(this.listenerKeys)) {
+ goog.array.forEach(this.listenerKeys, goog.events.unlistenByKey);
+ this.listenerKeys.length = 0;
+ }
+ goog.dom.classes.remove(this.element, 'active');
+};
+
+
+/**
+ * @param {ol.MapBrowserEvent} evt Event.
+ */
+ol.control.Select.prototype.handleClick = function(evt) {
+ this.getMap().getFeatures({
+ layers: this.layers_,
+ pixel: evt.getPixel(),
+ success: this.select
+ });
+};
+
+
+/**
+ * @param {Array.>} featuresByLayer Features by layer.
+ */
+ol.control.Select.prototype.select = function(featuresByLayer) {
+ // TODO: Do something with the features.
+};