diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index d45545b..81098ac 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -1451,6 +1451,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
 	void set_loop_from_selection (bool play);
 	void set_punch_from_selection ();
 	void set_punch_from_region ();
+	void set_punch_range_from_playhead ();
 
 	void set_session_start_from_playhead ();
 	void set_session_end_from_playhead ();
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index 79900b3..a4039e4 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -319,6 +319,7 @@ Editor::register_actions ()
 	reg_sens (editor_actions, "set-loop-from-edit-range", _("Set Loop from Selection"), sigc::bind (sigc::mem_fun(*this, &Editor::set_loop_from_selection), false));
 	reg_sens (editor_actions, "set-punch-from-edit-range", _("Set Punch from Selection"), sigc::mem_fun(*this, &Editor::set_punch_from_selection));
 	reg_sens (editor_actions, "set-session-from-edit-range", _("Set Session Start/End from Selection"), sigc::mem_fun(*this, &Editor::set_session_extents_from_selection));
+	reg_sens (editor_actions, "set-punch-range-from-playhead", _("Set Punch Range from Playhead"), sigc::mem_fun(*this, &Editor::set_punch_range_from_playhead));
 
 	/* this is a duplicated action so that the main menu can use a different label */
 	reg_sens (editor_actions, "main-menu-play-selected-regions", _("Play Selected Regions"), sigc::mem_fun (*this, &Editor::play_selected_region));
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index c208e55..af27c1b 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -2243,6 +2243,7 @@ Editor::set_session_end_from_playhead ()
 	_session->set_end_is_free (false);
 }
 
+
 void
 Editor::add_location_from_playhead_cursor ()
 {
@@ -6305,6 +6306,50 @@ Editor::set_punch_from_selection ()
 }
 
 void
+Editor::set_punch_range_from_playhead ()
+{
+	// auto punch in/out button from a single button
+	// If no punch range set - first press sets punch in.
+	// if punch in is set, the next punch sets punch out
+	// if punch out is set, it clears the punch range
+	if (_session == 0) {
+			return;
+	}
+
+	Location* tpl = transport_punch_location();
+	framepos_t now = playhead_cursor->current_frame();
+	framepos_t begin = now;
+	framepos_t end = _session->current_end_frame();
+
+	if (tpl == 0 && !_session->config.get_punch_in()) {
+		// First Press - set punch in and create range from here to eternity
+		set_punch_range (begin, end, _("Auto Punch In"));
+		_session->config.set_punch_in(true);
+	} else if (tpl && !_session->config.get_punch_out()) {
+		// Second press - update end range marker and set punch_out
+		if (now < tpl->start()) {
+			// playhead has been rewound - move start back  and pretend nothing happened
+			begin = now;
+			set_punch_range (begin, end, _("Auto Punch In/Out"));
+		} else {
+			// normal case for 2nd press - set the punch out
+			end = playhead_cursor->current_frame ();
+			set_punch_range (tpl->start(), now, _("Auto Punch In/Out"));
+			_session->config.set_punch_out(true);
+		}
+	} else 	{
+		if (tpl)
+		{
+			// third press - unset punch in/out and remove range
+			_session->config.set_punch_out(false);
+			_session->config.set_punch_in(false);
+			_session->locations()->remove(tpl);
+		}
+	}
+
+}
+
+void
 Editor::set_session_extents_from_selection ()
 {
 	if (_session == 0) {
